package cn.hznc.controller.service.schedule;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hznc.constant.CommonConstant;
import cn.hznc.controller.service.inventory.InventoryLocationService;
import cn.hznc.controller.service.process.ProcessManageService;
import cn.hznc.domain.entity.*;
import cn.hznc.domain.request.device.EquipmentOnlineDataReq;
import cn.hznc.domain.request.inventory.*;
import cn.hznc.domain.request.process.EmployeeTasksReq;
import cn.hznc.domain.request.process.UnmetToolReqReload;
import cn.hznc.domain.request.schedule.*;
import cn.hznc.domain.response.PageResult;
import cn.hznc.domain.response.ResponseBody;
import cn.hznc.exception.*;
import cn.hznc.mapper.*;
import cn.hznc.repository.*;
import cn.hznc.utils.CommonUtil;
import cn.hznc.vo.*;
import cn.nerc.nclink.core.communication.DeviceClient;
import cn.nerc.nclink.core.exception.InvalidIdException;
import cn.nerc.nclink.core.exception.InvalidItemException;
import cn.nerc.nclink.core.exception.InvalidMessageException;
import cn.nerc.nclink.core.exception.InvalidRequestException;
import cn.nerc.nclink.core.general.InvalidException;
import cn.nerc.nclink.core.general.Operation;
import cn.nerc.nclink.core.message.QueryRequestItem;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.github.pagehelper.util.StringUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeoutException;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;

/**
 * @Author：Administrator
 * @Date：2023/4/21 15:52
 */
@Service
@Slf4j
public class ToolScheduleService {

    @Resource
    private OrderRespository orderRespository;

    @Resource
    private InventoryLocationRespository inventoryLocationRespository;

    @Resource
    private ToolForkInfoRespository toolForkInfoRespository;

    @Resource
    private EmployeeRepository employeeRepository;

    @Resource
    private EmployeeMapper employeeMapper;

    @Resource
    private MachineToolTaskRespository machineToolTaskRespository;
    @Resource
    private ToolPartMapper toolPartMapper;

    @Resource
    private TypeMapper typeMapper;


    @Resource
    private EmployeeMachineToolConnectMapper employeeMachineToolConnectMapper;

    @Resource
    private AssemblyToolInventoryRepository assemblyToolInventoryRepository;

    @Autowired
    private InventoryLocationService inventoryLocationService;

    @Resource
    private ToolInventoryLocationRespository toolInventoryLocationRespository;

    @Resource
    private AssemblyToolInventoryMapper assemblyToolInventoryMapper;

    @Resource
    private ToolInventoryLocationMapper toolInventoryLocationMapper;

    @Resource
    private OrderMapper orderMapper;

    @Resource
    private ToolForkInfoMapper toolForkInfoMapper;


    @Resource
    private EquipmentGroupRepository equipmentGroupRepository;

    @Autowired
    private MinioProp minioProp;

    @Resource
    private WarehouseRespository warehouseRespository;

    @Resource
    private ToolLifeMapper toolLifeMapper;
    @Resource
    private ICabinetRecordMapper iCabinetRecordMapper;

    @Resource
    private ProcessManageService processManageService;

    @Resource
    private AllotEmployeeRepository allotEmployeeRepository;

    @Resource
    private ProgramDurationTimeMapper programDurationTimeMapper;

    @Resource
    private ProgramDurationTimeRepository programDurationTimeRepository;

    @Resource
    private MachineToolStatusRepository machineToolStatusRepository;

    @Resource
    private MachineToolDataLogRepository machineToolDataLogRepository;

    //连接对象内存map
    private static ConcurrentHashMap<String, DeviceClient> clientMap = new ConcurrentHashMap<>();

    private static final ConcurrentHashMap<String, Boolean> snFlagMap = new ConcurrentHashMap<>();

    private static final ConcurrentHashMap<String, List<IncBoxParamVo>> toolParamsMap = new ConcurrentHashMap<>();

    static {
        snFlagMap.put("B1", false);
        snFlagMap.put("B2", false);
        snFlagMap.put("B3", false);
        snFlagMap.put("B4", false);
        snFlagMap.put("B5", false);
        snFlagMap.put("B6", false);
        snFlagMap.put("B7", false);
        snFlagMap.put("B8", false);
        snFlagMap.put("B9", false);
        snFlagMap.put("B10", false);
        snFlagMap.put("B11", false);
        snFlagMap.put("B12", false);
        snFlagMap.put("B13", false);
        snFlagMap.put("B14", false);
        snFlagMap.put("B15", false);
        snFlagMap.put("B16", false);
        snFlagMap.put("B17", false);
    }


    public Object getToolDemandPredictionList(ToolDemandPredictionReq toolDemandPredictionReq) throws ToolScheduleException {
        List<String> taskIdList = toolDemandPredictionReq.getTaskIds();
        if (CollectionUtil.isEmpty(taskIdList)) {
            throw new ToolScheduleException(ToolManageEx.ORDER_NO_EXIST.getCode(), ToolManageEx.ORDER_NO_EXIST.getMsg());
        }
        if (ObjectUtil.isNull(toolDemandPredictionReq.getStartTime())) {
            toolDemandPredictionReq.setStartTime(new Date());
            toolDemandPredictionReq.setEndTime(CommonUtil.addTime48h());
        }
        List<Integer> idList = machineToolTaskRespository.selectIdsByTaskIds(toolDemandPredictionReq);
        List<OrderEntity> orderEntities = orderRespository.selectByTaskIdList(toolDemandPredictionReq.getTaskIds());
        //订单基本信息
        Map<String, Object> retMap = new HashMap<>();
        retMap.put("orderList", orderEntities);
        getToolList(toolDemandPredictionReq.getPageNum(), toolDemandPredictionReq.getPageSize(), idList, retMap, toolDemandPredictionReq.getTaskIds(), toolDemandPredictionReq.getSeqs(), toolDemandPredictionReq.getMachineToolIds());
        return retMap;
    }

//    public Object getToolDemandPredictionListReload(ToolDemandPredictionReq toolDemandPredictionReq) throws ToolScheduleException {
//        List<String> taskIdList = toolDemandPredictionReq.getTaskIds();
//        if (CollectionUtil.isEmpty(taskIdList)) {
//            throw new ToolScheduleException(ToolManageEx.ORDER_NO_EXIST.getCode(), ToolManageEx.ORDER_NO_EXIST.getMsg());
//        }
////        if(ObjectUtil.isNull(toolDemandPredictionReq.getStartTime())){
////            toolDemandPredictionReq.setStartTime(new Date());
////            toolDemandPredictionReq.setEndTime(CommonUtil.addTime48h());
////        }
//        List<Integer> idList = machineToolTaskRespository.selectIdsByTaskIds(toolDemandPredictionReq);
//        if (CollectionUtil.isNotEmpty(idList) && ObjectUtil.isNotNull(toolDemandPredictionReq.getId())) {
//            idList = idList.stream().filter(integer -> Objects.equals(integer, toolDemandPredictionReq.getId())).collect(Collectors.toList());
//        }
//        List<OrderEntity> orderEntities = orderRespository.selectByTaskIdList(toolDemandPredictionReq.getTaskIds());
//        //订单基本信息
//        Map<String, Object> retMap = new HashMap<>();
//        retMap.put("orderList", orderEntities);
//        getToolListReport(toolDemandPredictionReq.getPageNum(), toolDemandPredictionReq.getPageSize(), idList, retMap, toolDemandPredictionReq.getTaskIds(), toolDemandPredictionReq.getSeqs(), toolDemandPredictionReq.getMachineToolIds());
//        return retMap;
//    }

    public Object getToolDemandPredictionListReload1(ToolDemandPredictionReq toolDemandPredictionReq) throws ToolScheduleException {
        List<String> taskIdList = toolDemandPredictionReq.getTaskIds();
        if (CollectionUtil.isEmpty(taskIdList)) {
            throw new ToolScheduleException(ToolManageEx.ORDER_NO_EXIST.getCode(), ToolManageEx.ORDER_NO_EXIST.getMsg());
        }
//        if(ObjectUtil.isNull(toolDemandPredictionReq.getStartTime())){
//            toolDemandPredictionReq.setStartTime(new Date());
//            toolDemandPredictionReq.setEndTime(CommonUtil.addTime48h());
//        }
        List<Integer> idList = machineToolTaskRespository.selectIdsByTaskIds(toolDemandPredictionReq);
        if (CollectionUtil.isNotEmpty(idList) && ObjectUtil.isNotNull(toolDemandPredictionReq.getId())) {
            idList = idList.stream().filter(integer -> Objects.equals(integer, toolDemandPredictionReq.getId())).collect(Collectors.toList());
        }
        List<OrderEntity> orderEntities = orderRespository.selectByTaskIdList(toolDemandPredictionReq.getTaskIds());
        //订单基本信息
        Map<String, Object> retMap = new HashMap<>();
        retMap.put("orderList", orderEntities);
        getToolListReport1(toolDemandPredictionReq.getPageNum(), toolDemandPredictionReq.getPageSize(), idList, retMap, toolDemandPredictionReq.getTaskIds(), toolDemandPredictionReq.getSeqs(), toolDemandPredictionReq.getMachineToolIds(), toolDemandPredictionReq.getFlag());
        return retMap;
    }

    /**
     * 获取刀具需求预测的刀具清单
     *
     * @param idList
     * @param retMap
     */
    private void getToolList(Integer pageNum, Integer pageSize, List<Integer> idList, Map<String, Object> retMap, List<String> qryTaskIds, List<Integer> qrySeqs, List<Integer> machineToolIds) {
        if (CollectionUtil.isEmpty(idList)) {
            //工单未分配任务
            retMap.put("toolList", new ArrayList<>());
            retMap.put("total", 0);
            return;
        }
        //获取刀具清单
        List<ToolDemandPredictionParamVo> toolParamList = orderRespository.getToolDemandPredictionList(idList);
        //刀具清单列表不为空(新建工单快照程序信息逻辑为：工序未关联主程序就不持久化到工单程序快照表中)
        if (CollectionUtil.isNotEmpty(toolParamList)) {
            //过滤掉未关联子程序的
            List<ToolDemandPredictionVo> toolList = new ArrayList<>();
            for (ToolDemandPredictionParamVo toolDemandPredictionParamVo : toolParamList) {
                if (ObjectUtil.isNotNull(toolDemandPredictionParamVo.getSubProgramParam())) {
                    List<ToolDemandPredictionVo> toolDemandPredictionVos = buildToolDemandPredictionVo(toolDemandPredictionParamVo);
                    toolList.addAll(Objects.requireNonNull(toolDemandPredictionVos));
                } else {
                    //去产品表找程序数据
                    List<SubProgramParamVo> subProgramEntityList = orderRespository.selectProgram(toolDemandPredictionParamVo.getTaskId(), toolDemandPredictionParamVo.getSeq());
                    if (CollectionUtil.isEmpty(subProgramEntityList)) {
                        continue;
                    }
                    toolDemandPredictionParamVo.setSubProgramParamVoList(subProgramEntityList);
                    //计算单个程序平均耗时
                    toolDemandPredictionParamVo.setSingleTime(toolDemandPredictionParamVo.getHandleTime().divide(new BigDecimal(subProgramEntityList.size()), BigDecimal.ROUND_CEILING));
                    List<ToolDemandPredictionVo> toolDemandPredictionVos = buildToolDemandPredictionVoReload(toolDemandPredictionParamVo);
                    toolList.addAll(Objects.requireNonNull(toolDemandPredictionVos));

                }
            }
            //List<ToolDemandPredictionVo> pageList = CommonUtil.pageList(toolList, pageNum, pageSize);
            //工单号和工序号筛选不为空 则过滤
            if (CollectionUtil.isNotEmpty(qryTaskIds)) {
                //查询指定工单号下所有工序的数据
                toolList = toolList
                        .stream()
                        .filter(toolDemandPredictionVo -> qryTaskIds.contains(toolDemandPredictionVo.getTaskId()))
                        .collect(Collectors.toList());
                if (CollectionUtil.isNotEmpty(qrySeqs)) {
                    //查询指定工单号下指定工序号的数据
                    toolList = toolList
                            .stream()
                            .filter(toolDemandPredictionVo -> qrySeqs.contains(toolDemandPredictionVo.getSeq()))
                            .collect(Collectors.toList());
                }
            }

            //机床id不为空 则根据机床id过滤
            if (CollectionUtil.isNotEmpty(machineToolIds)) {
                toolList = toolList.stream().filter(toolDemandPredictionVo -> machineToolIds.contains(toolDemandPredictionVo.getMachineToolId())).collect(Collectors.toList());
            }

            List<ToolDemandPredictionVo> pageList = new ArrayList<>();
            List<TaskIdGroupVo> taskIdGroupVos = new ArrayList<>();
            retMap.put("groupList", taskIdGroupVos);
            buildStatus(toolList);
            if (CollectionUtil.isNotEmpty(toolList)) {
                toolList = toolList.stream().sorted(Comparator.comparing(ToolDemandPredictionVo::getStatus, Comparator.nullsFirst(String::compareTo))).collect(Collectors.toList());
                pageList = CommonUtil.pageList(toolList, pageNum, pageSize);
            }
            if (CollectionUtil.isNotEmpty(toolList)) {
                //结果分组工单号，以及工单号对应的工序序列号
                List<String> taskIds = toolList
                        .stream()
                        .map(ToolDemandPredictionVo::getTaskId).distinct()
                        .collect(Collectors.toList());
                if (CollectionUtil.isNotEmpty(taskIds)) {
                    List<ToolDemandPredictionVo> groupList = new ArrayList<>();
                    for (String taskId : taskIds) {
                        TaskIdGroupVo taskIdGroupVo = new TaskIdGroupVo();
                        //循环分组工单号，并印射工单号对应的工序号数组
                        groupList = toolList.stream()
                                .filter(toolDemandPredictionVo ->
                                        ObjectUtil.isNotNull(toolDemandPredictionVo.getTaskId()) && taskId.equals(toolDemandPredictionVo.getTaskId()))
                                .collect(Collectors.toList());
                        taskIdGroupVo.setTaskId(taskId);
                        if (CollectionUtil.isNotEmpty(groupList)) {
                            List<Integer> seqs = groupList.stream()
                                    .map(ToolDemandPredictionVo::getSeq)
                                    .distinct()
                                    .collect(Collectors.toList());
                            taskIdGroupVo.setSeqs(seqs);
                        } else {
                            taskIdGroupVo.setSeqs(new ArrayList<>());
                        }
                        taskIdGroupVos.add(taskIdGroupVo);
                    }
                }
                retMap.put("groupList", taskIdGroupVos);

            }
            pageList = pageList.stream().sorted(Comparator.comparing(ToolDemandPredictionVo::getToolCode)).collect(Collectors.toList());
            retMap.put("toolList", pageList);
            retMap.put("total", toolList.size());
        } else {
            //分配的任务未关联子程序
            retMap.put("groupList", new ArrayList<>());
            retMap.put("toolList", new ArrayList<>());
            retMap.put("total", 0);
        }
    }

    private void getToolListReport1(Integer pageNum, Integer pageSize, List<Integer> idList, Map<String, Object> retMap, List<String> qryTaskIds, List<Integer> qrySeqs, List<Integer> machineToolIds, Boolean flag) {
        if (CollectionUtil.isEmpty(idList)) {
            //工单未分配任务
            retMap.put("toolList", new ArrayList<>());
            retMap.put("total", 0);
            return;
        }
        //获取刀具清单
        List<ToolDemandPredictionParamVo> toolParamList = orderRespository.getToolDemandPredictionList1(idList);
        //刀具清单列表不为空(新建工单快照程序信息逻辑为：工序未关联主程序就不持久化到工单程序快照表中)
        if (CollectionUtil.isNotEmpty(toolParamList)) {
            //过滤掉未关联子程序的
            List<ToolDemandPredictionVo> toolList = new ArrayList<>();
            for (ToolDemandPredictionParamVo toolDemandPredictionParamVo : toolParamList) {
                if (ObjectUtil.isNotNull(toolDemandPredictionParamVo.getSubProgramParam())) {
                    List<ToolDemandPredictionVo> toolDemandPredictionVos = buildToolDemandPredictionVo(toolDemandPredictionParamVo);
                    toolList.addAll(Objects.requireNonNull(toolDemandPredictionVos));
                } else {
                    //去产品表找程序数据
                    List<SubProgramParamVo> subProgramEntityList = orderRespository.selectProgram(toolDemandPredictionParamVo.getTaskId(), toolDemandPredictionParamVo.getSeq());
                    if (CollectionUtil.isEmpty(subProgramEntityList)) {
                        continue;
                    }
                    toolDemandPredictionParamVo.setSubProgramParamVoList(subProgramEntityList);
                    //计算单个程序平均耗时
                    toolDemandPredictionParamVo.setSingleTime(toolDemandPredictionParamVo.getHandleTime().divide(new BigDecimal(subProgramEntityList.size()), BigDecimal.ROUND_CEILING));
                    List<ToolDemandPredictionVo> toolDemandPredictionVos = buildToolDemandPredictionVoReload1(toolDemandPredictionParamVo, flag);
                    toolList.addAll(Objects.requireNonNull(toolDemandPredictionVos));

                }
            }
            //List<ToolDemandPredictionVo> pageList = CommonUtil.pageList(toolList, pageNum, pageSize);
            //工单号和工序号筛选不为空 则过滤
            if (CollectionUtil.isNotEmpty(qryTaskIds)) {
                //查询指定工单号下所有工序的数据
                toolList = toolList
                        .stream()
                        .filter(toolDemandPredictionVo -> qryTaskIds.contains(toolDemandPredictionVo.getTaskId()))
                        .collect(Collectors.toList());
                if (CollectionUtil.isNotEmpty(qrySeqs)) {
                    //查询指定工单号下指定工序号的数据
                    toolList = toolList
                            .stream()
                            .filter(toolDemandPredictionVo -> qrySeqs.contains(toolDemandPredictionVo.getSeq()))
                            .collect(Collectors.toList());
                }
            }

            //机床id不为空 则根据机床id过滤
            if (CollectionUtil.isNotEmpty(machineToolIds)) {
                toolList = toolList.stream().filter(toolDemandPredictionVo -> machineToolIds.contains(toolDemandPredictionVo.getMachineToolId())).collect(Collectors.toList());
            }

            List<ToolDemandPredictionVo> pageList = new ArrayList<>();
            List<TaskIdGroupVo> taskIdGroupVos = new ArrayList<>();
            retMap.put("groupList", taskIdGroupVos);
            buildStatusReport(toolList);
            if (CollectionUtil.isNotEmpty(toolList)) {
                //结果分组工单号，以及工单号对应的工序序列号
                List<String> taskIds = toolList
                        .stream()
                        .map(ToolDemandPredictionVo::getTaskId).distinct()
                        .collect(Collectors.toList());
                if (CollectionUtil.isNotEmpty(taskIds)) {
                    List<ToolDemandPredictionVo> groupList = new ArrayList<>();
                    for (String taskId : taskIds) {
                        TaskIdGroupVo taskIdGroupVo = new TaskIdGroupVo();
                        //循环分组工单号，并印射工单号对应的工序号数组
                        groupList = toolList.stream()
                                .filter(toolDemandPredictionVo ->
                                        ObjectUtil.isNotNull(toolDemandPredictionVo.getTaskId()) && taskId.equals(toolDemandPredictionVo.getTaskId()))
                                .collect(Collectors.toList());
                        taskIdGroupVo.setTaskId(taskId);
                        if (CollectionUtil.isNotEmpty(groupList)) {
                            List<Integer> seqs = groupList.stream()
                                    .map(ToolDemandPredictionVo::getSeq)
                                    .distinct()
                                    .collect(Collectors.toList());
                            taskIdGroupVo.setSeqs(seqs);
                        } else {
                            taskIdGroupVo.setSeqs(new ArrayList<>());
                        }
                        taskIdGroupVos.add(taskIdGroupVo);
                    }
                }
                retMap.put("groupList", taskIdGroupVos);
                pageList = CommonUtil.pageList(toolList, pageNum, pageSize);
            }
            retMap.put("allToolList", toolList);
            retMap.put("toolList", pageList);
            retMap.put("total", toolList.size());
        } else {
            //分配的任务未关联子程序
            retMap.put("allToolList", new ArrayList<>());
            retMap.put("groupList", new ArrayList<>());
            retMap.put("toolList", new ArrayList<>());
            retMap.put("total", 0);
        }
    }

    /**
     * 获取刀具需求预测的刀具清单
     *
     * @param idList
     * @param retMap
     */
//    private void getToolListReport(Integer pageNum, Integer pageSize, List<Integer> idList, Map<String, Object> retMap, List<String> qryTaskIds, List<Integer> qrySeqs, List<Integer> machineToolIds) {
//        if (CollectionUtil.isEmpty(idList)) {
//            //工单未分配任务
//            retMap.put("toolList", new ArrayList<>());
//            retMap.put("total", 0);
//            return;
//        }
//        //获取刀具清单
//        List<ToolDemandPredictionParamVo> toolParamList = orderRespository.getToolDemandPredictionList(idList);
//        //刀具清单列表不为空(新建工单快照程序信息逻辑为：工序未关联主程序就不持久化到工单程序快照表中)
//        if (CollectionUtil.isNotEmpty(toolParamList)) {
//            //过滤掉未关联子程序的
//            List<ToolDemandPredictionVo> toolList = new ArrayList<>();
//            for (ToolDemandPredictionParamVo toolDemandPredictionParamVo : toolParamList) {
//                if (ObjectUtil.isNotNull(toolDemandPredictionParamVo.getSubProgramParam())) {
//                    List<ToolDemandPredictionVo> toolDemandPredictionVos = buildToolDemandPredictionVo(toolDemandPredictionParamVo);
//                    toolList.addAll(Objects.requireNonNull(toolDemandPredictionVos));
//                } else {
//                    //去产品表找程序数据
//                    List<SubProgramParamVo> subProgramEntityList = orderRespository.selectProgram(toolDemandPredictionParamVo.getTaskId(), toolDemandPredictionParamVo.getSeq());
//                    if (CollectionUtil.isEmpty(subProgramEntityList)) {
//                        continue;
//                    }
//                    toolDemandPredictionParamVo.setSubProgramParamVoList(subProgramEntityList);
//                    //计算单个程序平均耗时
//                    toolDemandPredictionParamVo.setSingleTime(toolDemandPredictionParamVo.getHandleTime().divide(new BigDecimal(subProgramEntityList.size()), BigDecimal.ROUND_CEILING));
//                    List<ToolDemandPredictionVo> toolDemandPredictionVos = buildToolDemandPredictionVoReload(toolDemandPredictionParamVo);
//                    toolList.addAll(Objects.requireNonNull(toolDemandPredictionVos));
//
//                }
//            }
//            //List<ToolDemandPredictionVo> pageList = CommonUtil.pageList(toolList, pageNum, pageSize);
//            //工单号和工序号筛选不为空 则过滤
//            if (CollectionUtil.isNotEmpty(qryTaskIds)) {
//                //查询指定工单号下所有工序的数据
//                toolList = toolList
//                        .stream()
//                        .filter(toolDemandPredictionVo -> qryTaskIds.contains(toolDemandPredictionVo.getTaskId()))
//                        .collect(Collectors.toList());
//                if (CollectionUtil.isNotEmpty(qrySeqs)) {
//                    //查询指定工单号下指定工序号的数据
//                    toolList = toolList
//                            .stream()
//                            .filter(toolDemandPredictionVo -> qrySeqs.contains(toolDemandPredictionVo.getSeq()))
//                            .collect(Collectors.toList());
//                }
//            }
//
//            //机床id不为空 则根据机床id过滤
//            if (CollectionUtil.isNotEmpty(machineToolIds)) {
//                toolList = toolList.stream().filter(toolDemandPredictionVo -> machineToolIds.contains(toolDemandPredictionVo.getMachineToolId())).collect(Collectors.toList());
//            }
//
//            List<ToolDemandPredictionVo> pageList = new ArrayList<>();
//            List<TaskIdGroupVo> taskIdGroupVos = new ArrayList<>();
//            retMap.put("groupList", taskIdGroupVos);
//            buildStatusReport(toolList);
//            if (CollectionUtil.isNotEmpty(toolList)) {
//                //结果分组工单号，以及工单号对应的工序序列号
//                List<String> taskIds = toolList
//                        .stream()
//                        .map(ToolDemandPredictionVo::getTaskId).distinct()
//                        .collect(Collectors.toList());
//                if (CollectionUtil.isNotEmpty(taskIds)) {
//                    List<ToolDemandPredictionVo> groupList = new ArrayList<>();
//                    for (String taskId : taskIds) {
//                        TaskIdGroupVo taskIdGroupVo = new TaskIdGroupVo();
//                        //循环分组工单号，并印射工单号对应的工序号数组
//                        groupList = toolList.stream()
//                                .filter(toolDemandPredictionVo ->
//                                        ObjectUtil.isNotNull(toolDemandPredictionVo.getTaskId()) && taskId.equals(toolDemandPredictionVo.getTaskId()))
//                                .collect(Collectors.toList());
//                        taskIdGroupVo.setTaskId(taskId);
//                        if (CollectionUtil.isNotEmpty(groupList)) {
//                            List<Integer> seqs = groupList.stream()
//                                    .map(ToolDemandPredictionVo::getSeq)
//                                    .distinct()
//                                    .collect(Collectors.toList());
//                            taskIdGroupVo.setSeqs(seqs);
//                        } else {
//                            taskIdGroupVo.setSeqs(new ArrayList<>());
//                        }
//                        taskIdGroupVos.add(taskIdGroupVo);
//                    }
//                }
//                retMap.put("groupList", taskIdGroupVos);
//                pageList = CommonUtil.pageList(toolList, pageNum, pageSize);
//            }
//            retMap.put("allToolList", toolList);
//            retMap.put("toolList", pageList);
//            retMap.put("total", toolList.size());
//        } else {
//            //分配的任务未关联子程序
//            retMap.put("allToolList", new ArrayList<>());
//            retMap.put("groupList", new ArrayList<>());
//            retMap.put("toolList", new ArrayList<>());
//            retMap.put("total", 0);
//        }
//    }


    /**
     * 获取刀具需求预测的刀具清单(人员需求预测)
     *
     * @param idList
     * @param retMap
     */
    private void getToolListReload(Integer pageNum, Integer pageSize, List<Integer> idList, Map<String, Object> retMap, List<String> qryTaskIds, List<Integer> qrySeqs, List<Integer> machineToolIds) {
        if (CollectionUtil.isEmpty(idList)) {
            //工单未分配任务
            retMap.put("toolList", new ArrayList<>());
            retMap.put("total", 0);
            return;
        }
        //获取刀具清单
        List<ToolDemandPredictionParamVo> toolParamList = orderRespository.getToolDemandPredictionList(idList);
        //刀具清单列表不为空(新建工单快照程序信息逻辑为：工序未关联主程序就不持久化到工单程序快照表中)
        if (CollectionUtil.isNotEmpty(toolParamList)) {
            //过滤掉未关联子程序的
            List<ToolDemandPredictionVo> toolList = new ArrayList<>();
            for (ToolDemandPredictionParamVo toolDemandPredictionParamVo : toolParamList) {
                if (ObjectUtil.isNotNull(toolDemandPredictionParamVo.getSubProgramParam())) {
                    List<ToolDemandPredictionVo> toolDemandPredictionVos = buildToolDemandPredictionVo(toolDemandPredictionParamVo);
                    toolList.addAll(Objects.requireNonNull(toolDemandPredictionVos));
                } else {
                    //去产品表找程序数据
                    List<SubProgramParamVo> subProgramEntityList = orderRespository.selectProgram(toolDemandPredictionParamVo.getTaskId(), toolDemandPredictionParamVo.getSeq());
                    if (CollectionUtil.isEmpty(subProgramEntityList)) {
                        continue;
                    }
                    toolDemandPredictionParamVo.setSubProgramParamVoList(subProgramEntityList);
                    toolDemandPredictionParamVo.setSingleTime(toolDemandPredictionParamVo.getHandleTime().divide(new BigDecimal(subProgramEntityList.size()), BigDecimal.ROUND_CEILING));
                    List<ToolDemandPredictionVo> toolDemandPredictionVos = buildToolDemandPredictionVoReload(toolDemandPredictionParamVo);
                    toolList.addAll(Objects.requireNonNull(toolDemandPredictionVos));
                }
            }
            //工单号和工序号筛选不为空 则过滤
            if (CollectionUtil.isNotEmpty(qryTaskIds)) {
                //查询指定工单号下所有工序的数据
                toolList = toolList
                        .stream()
                        .filter(toolDemandPredictionVo -> qryTaskIds.contains(toolDemandPredictionVo.getTaskId()))
                        .collect(Collectors.toList());
                if (CollectionUtil.isNotEmpty(qrySeqs)) {
                    //查询指定工单号下指定工序号的数据
                    toolList = toolList
                            .stream()
                            .filter(toolDemandPredictionVo -> qrySeqs.contains(toolDemandPredictionVo.getSeq()))
                            .collect(Collectors.toList());
                }
            }

            //机床id不为空 则根据机床id过滤
            if (CollectionUtil.isNotEmpty(machineToolIds)) {
                toolList = toolList.stream().filter(toolDemandPredictionVo -> machineToolIds.contains(toolDemandPredictionVo.getMachineToolId())).collect(Collectors.toList());
            }

            List<ToolDemandPredictionVo> pageList = new ArrayList<>();
            List<TaskIdGroupVo> taskIdGroupVos = new ArrayList<>();
            retMap.put("groupList", taskIdGroupVos);
            if (CollectionUtil.isNotEmpty(toolList)) {
                //结果分组工单号，以及工单号对应的工序序列号
                List<String> taskIds = toolList
                        .stream()
                        .map(ToolDemandPredictionVo::getTaskId).distinct()
                        .collect(Collectors.toList());
                if (CollectionUtil.isNotEmpty(taskIds)) {
                    for (String taskId : taskIds) {
                        TaskIdGroupVo taskIdGroupVo = new TaskIdGroupVo();
                        //循环分组工单号，并印射工单号对应的工序号数组
                        toolList = toolList.stream()
                                .filter(toolDemandPredictionVo ->
                                        ObjectUtil.isNotNull(toolDemandPredictionVo.getTaskId()) && taskId.equals(toolDemandPredictionVo.getTaskId()))
                                .collect(Collectors.toList());
                        taskIdGroupVo.setTaskId(taskId);
                        if (CollectionUtil.isNotEmpty(toolList)) {
                            List<Integer> seqs = toolList.stream()
                                    .map(ToolDemandPredictionVo::getSeq)
                                    .distinct()
                                    .collect(Collectors.toList());
                            taskIdGroupVo.setSeqs(seqs);
                        } else {
                            taskIdGroupVo.setSeqs(new ArrayList<>());
                        }
                        taskIdGroupVos.add(taskIdGroupVo);
                    }
                }
                retMap.put("groupList", taskIdGroupVos);
                pageList = CommonUtil.pageList(toolList, pageNum, pageSize);
            }
            //List<ToolDemandPredictionVo> pageList = CommonUtil.pageList(toolList, pageNum, pageSize);
            buildStatusReload(pageList);
            pageList = pageList.stream().sorted(Comparator.comparing(ToolDemandPredictionVo::getToolCode)).collect(Collectors.toList());
            retMap.put("toolList", pageList);
            retMap.put("total", toolList.size());
        } else {
            //分配的任务未关联子程序
            retMap.put("toolList", new ArrayList<>());
            retMap.put("total", 0);
        }
    }

    public List<ToolDemandPredictionVo> getToolListMessage(Integer pageNum, Integer pageSize, List<Integer> idList) {
        if (CollectionUtil.isEmpty(idList)) {
            //工单未分配任务
            return new ArrayList<>();
        }
        //获取刀具清单
        List<ToolDemandPredictionParamVo> toolParamList = orderRespository.getToolDemandPredictionList(idList);
        //刀具清单列表不为空(新建工单快照程序信息逻辑为：工序未关联主程序就不持久化到工单程序快照表中)
        if (CollectionUtil.isNotEmpty(toolParamList)) {
            //过滤掉未关联子程序的
            List<ToolDemandPredictionVo> toolList = new ArrayList<>();
            for (ToolDemandPredictionParamVo toolDemandPredictionParamVo : toolParamList) {
                if (ObjectUtil.isNotNull(toolDemandPredictionParamVo.getSubProgramParam())) {
                    List<ToolDemandPredictionVo> toolDemandPredictionVos = buildToolDemandPredictionVo(toolDemandPredictionParamVo);
                    toolList.addAll(Objects.requireNonNull(toolDemandPredictionVos));
                } else {
                    //去产品表找程序数据
                    List<SubProgramParamVo> subProgramEntityList = orderRespository.selectProgram(toolDemandPredictionParamVo.getTaskId(), toolDemandPredictionParamVo.getSeq());
                    if (CollectionUtil.isEmpty(subProgramEntityList)) {
                        continue;
                    }
                    toolDemandPredictionParamVo.setSubProgramParamVoList(subProgramEntityList);
                    toolDemandPredictionParamVo.setSingleTime(toolDemandPredictionParamVo.getHandleTime().divide(new BigDecimal(subProgramEntityList.size()), BigDecimal.ROUND_CEILING));
                    List<ToolDemandPredictionVo> toolDemandPredictionVos = buildToolDemandPredictionVoReload(toolDemandPredictionParamVo);
                    toolList.addAll(Objects.requireNonNull(toolDemandPredictionVos));
                }
            }
            List<ToolDemandPredictionVo> pageList = new ArrayList<>();
            List<TaskIdGroupVo> taskIdGroupVos = new ArrayList<>();
            if (CollectionUtil.isNotEmpty(toolList)) {
                //结果分组工单号，以及工单号对应的工序序列号
                List<String> taskIds = toolList
                        .stream()
                        .map(ToolDemandPredictionVo::getTaskId).distinct()
                        .collect(Collectors.toList());
                if (CollectionUtil.isNotEmpty(taskIds)) {
                    for (String taskId : taskIds) {
                        TaskIdGroupVo taskIdGroupVo = new TaskIdGroupVo();
                        //循环分组工单号，并印射工单号对应的工序号数组
                        toolList = toolList.stream()
                                .filter(toolDemandPredictionVo ->
                                        ObjectUtil.isNotNull(toolDemandPredictionVo.getTaskId()) && taskId.equals(toolDemandPredictionVo.getTaskId()))
                                .collect(Collectors.toList());
                        taskIdGroupVo.setTaskId(taskId);
                        if (CollectionUtil.isNotEmpty(toolList)) {
                            List<Integer> seqs = toolList.stream()
                                    .map(ToolDemandPredictionVo::getSeq)
                                    .distinct()
                                    .collect(Collectors.toList());
                            taskIdGroupVo.setSeqs(seqs);
                        } else {
                            taskIdGroupVo.setSeqs(new ArrayList<>());
                        }
                        taskIdGroupVos.add(taskIdGroupVo);
                    }
                }
                pageList = CommonUtil.pageList(toolList, pageNum, pageSize);
            }
            //List<ToolDemandPredictionVo> pageList = CommonUtil.pageList(toolList, pageNum, pageSize);
            //buildStatusReload(pageList);
            buildStatus(pageList);
            pageList = pageList.stream().sorted(Comparator.comparing(ToolDemandPredictionVo::getToolCode)).collect(Collectors.toList());
            return pageList;
        } else {
            //分配的任务未关联子程序
            return new ArrayList<>();
        }
    }

    /**
     * 获取刀具需求预测的刀具清单
     *
     * @param idList
     * @param retMap
     */
    private void getToolList(Integer pageNum, Integer pageSize, List<Integer> idList, Map<String, Object> retMap, Boolean flag, List<String> qryTaskIds, List<Integer> qrySeqs) {
        if (CollectionUtil.isEmpty(idList)) {
            //工单未分配任务
            retMap.put("toolList", new ArrayList<>());
            retMap.put("total", 0);
            return;
        }
        //获取刀具清单
        List<ToolDemandPredictionParamVo> toolParamList = orderRespository.getToolDemandPredictionList(idList);
        //刀具清单列表不为空(新建工单快照程序信息逻辑为：工序未关联主程序就不持久化到工单程序快照表中)
        if (CollectionUtil.isNotEmpty(toolParamList)) {
            //过滤掉未关联子程序的
            List<ToolDemandPredictionVo> toolList = new ArrayList<>();
            for (ToolDemandPredictionParamVo toolDemandPredictionParamVo : toolParamList) {
                if (ObjectUtil.isNotNull(toolDemandPredictionParamVo.getSubProgramParam())) {
                    List<ToolDemandPredictionVo> toolDemandPredictionVos = buildToolDemandPredictionVo(toolDemandPredictionParamVo);
                    toolList.addAll(Objects.requireNonNull(toolDemandPredictionVos));
                } else {
                    //去产品表找程序数据
                    List<SubProgramParamVo> subProgramEntityList = orderRespository.selectProgram(toolDemandPredictionParamVo.getTaskId(), toolDemandPredictionParamVo.getSeq());
                    toolDemandPredictionParamVo.setSubProgramParamVoList(subProgramEntityList);
                    //计算单个程序平均耗时
                    if (CollectionUtil.isNotEmpty(subProgramEntityList)) {
                        toolDemandPredictionParamVo.setSingleTime(toolDemandPredictionParamVo.getHandleTime().divide(new BigDecimal(subProgramEntityList.size()), BigDecimal.ROUND_CEILING));
                        List<ToolDemandPredictionVo> toolDemandPredictionVos = buildToolDemandPredictionVoReload(toolDemandPredictionParamVo);
                        toolList.addAll(Objects.requireNonNull(toolDemandPredictionVos));
                    }
                }
            }
            buildStatus(toolList);
            if (flag) {
                //查所有
                toolList = toolList.stream().filter(toolDemandPredictionVo -> ObjectUtil.isNotNull(toolDemandPredictionVo.getStatus()) && toolDemandPredictionVo.getStatus().equals(CommonConstant.NOT_SATISFIED_CONST)).collect(Collectors.toList());
            }
            //工单号和工序号筛选不为空 则过滤
            if (CollectionUtil.isNotEmpty(qryTaskIds)) {
                //查询指定工单号下所有工序的数据
                toolList = toolList
                        .stream()
                        .filter(toolDemandPredictionVo -> qryTaskIds.contains(toolDemandPredictionVo.getTaskId()))
                        .collect(Collectors.toList());
                if (CollectionUtil.isNotEmpty(qrySeqs)) {
                    //查询指定工单号下指定工序号的数据
                    toolList = toolList
                            .stream()
                            .filter(toolDemandPredictionVo -> qrySeqs.contains(toolDemandPredictionVo.getSeq()))
                            .collect(Collectors.toList());
                }
            }

            List<ToolDemandPredictionVo> pageList = new ArrayList<>();
            List<TaskIdGroupVo> taskIdGroupVos = new ArrayList<>();
            retMap.put("groupList", taskIdGroupVos);
            if (CollectionUtil.isNotEmpty(toolList)) {
                //结果分组工单号，以及工单号对应的工序序列号
                List<String> taskIds = toolList
                        .stream()
                        .map(ToolDemandPredictionVo::getTaskId).distinct()
                        .collect(Collectors.toList());
                if (CollectionUtil.isNotEmpty(taskIds)) {
                    List<ToolDemandPredictionVo> groupList = new ArrayList<>();
                    for (String taskId : taskIds) {
                        TaskIdGroupVo taskIdGroupVo = new TaskIdGroupVo();
                        //循环分组工单号，并印射工单号对应的工序号数组
                        groupList = toolList.stream()
                                .filter(toolDemandPredictionVo ->
                                        ObjectUtil.isNotNull(toolDemandPredictionVo.getTaskId()) && taskId.equals(toolDemandPredictionVo.getTaskId()))
                                .collect(Collectors.toList());
                        taskIdGroupVo.setTaskId(taskId);
                        if (CollectionUtil.isNotEmpty(groupList)) {
                            List<Integer> seqs = groupList.stream()
                                    .map(ToolDemandPredictionVo::getSeq)
                                    .distinct()
                                    .collect(Collectors.toList());
                            taskIdGroupVo.setSeqs(seqs);
                        } else {
                            taskIdGroupVo.setSeqs(new ArrayList<>());
                        }
                        taskIdGroupVos.add(taskIdGroupVo);
                    }
                }
                retMap.put("groupList", taskIdGroupVos);
                //toolList = toolList.stream().sorted(Comparator.comparing(ToolDemandPredictionVo::getToolCode)).collect(Collectors.toList());
                pageList = CommonUtil.pageList(toolList, pageNum, pageSize);

                //设置排班人员信息
                if (CollectionUtil.isNotEmpty(pageList)) {
                    pageList.forEach(toolDemandPredictionVo -> {
                        //toolDemandPredictionVo.setEmployeeName(machineToolTaskRespository.selectCurrentEmployeeTask(toolDemandPredictionVo.getMachineToolName() , new Date()));
                    });
                }
            }
            retMap.put("toolList", pageList);
            retMap.put("total", toolList.size());
        } else {
            //分配的任务未关联子程序
            retMap.put("groupList", new ArrayList<>());
            retMap.put("toolList", new ArrayList<>());
            retMap.put("total", 0);
        }
    }

    private void getUnmetTool(Integer pageNum, Integer pageSize, List<Integer> idList, Map<String, Object> retMap, Boolean flag, List<String> qryTaskIds, List<Integer> qrySeqs, Boolean flag2) {
        if (CollectionUtil.isEmpty(idList)) {
            //工单未分配任务
            retMap.put("toolList", new ArrayList<>());
            retMap.put("total", 0);
            return;
        }
        //获取刀具清单
        List<ToolDemandPredictionParamVo> toolParamList = orderRespository.getToolDemandPredictionList(idList);
        //刀具清单列表不为空(新建工单快照程序信息逻辑为：工序未关联主程序就不持久化到工单程序快照表中)
        if (CollectionUtil.isNotEmpty(toolParamList)) {
            //过滤掉未关联子程序的
            List<ToolDemandPredictionVo> toolList = new ArrayList<>();
            for (ToolDemandPredictionParamVo toolDemandPredictionParamVo : toolParamList) {
                if (ObjectUtil.isNotNull(toolDemandPredictionParamVo.getSubProgramParam())) {
                    List<ToolDemandPredictionVo> toolDemandPredictionVos = buildToolDemandPredictionVo(toolDemandPredictionParamVo);
                    toolList.addAll(Objects.requireNonNull(toolDemandPredictionVos));
                } else {
                    //去产品表找程序数据
                    List<SubProgramParamVo> subProgramEntityList = orderRespository.selectProgram(toolDemandPredictionParamVo.getTaskId(), toolDemandPredictionParamVo.getSeq());
                    //计算单个程序平均耗时
                    if (CollectionUtil.isNotEmpty(subProgramEntityList)) {
                        if (ObjectUtil.isNotNull(flag2) && flag2) {
                            //需要整合
                            if (CollectionUtil.isNotEmpty(subProgramEntityList)) {
                                BigDecimal subProgramListSize = new BigDecimal(subProgramEntityList.size());
                                //获取反填时间map
                                List<SubProgramUsageReportVo> totalSubProgramUsageReportVos = programDurationTimeRepository.selectByProgramNameReload(subProgramEntityList.stream().map(SubProgramParamVo::getName).collect(Collectors.toList()));
                                //List<SubProgramUsageReportVo> totalSubProgramUsageReportVos = programDurationTimeRepository.selectProgramDuration(subProgramEntityList.stream().map(SubProgramParamVo::getName).collect(Collectors.toList()));
                                Map<String, List<SubProgramUsageReportVo>> groupBySubprogramNameMap = totalSubProgramUsageReportVos.stream().collect(Collectors.groupingBy(SubProgramUsageReportVo::getProgram));
                                for (SubProgramParamVo subProgramParamVo : subProgramEntityList) {
                                    //获取平均时间
                                    subProgramParamVo.setAvgTime(toolDemandPredictionParamVo.getHandleTime().divide(subProgramListSize, BigDecimal.ROUND_CEILING));
                                    //获取反填时间
                                    List<SubProgramUsageReportVo> subProgramUsageReportVos = groupBySubprogramNameMap.getOrDefault(subProgramParamVo.getName(), new ArrayList<>());
                                    //List<SubProgramUsageReportVo> subProgramUsageReportVos = programDurationTimeRepository.selectByProgramName(subProgramParamVo.getName());
                                    if (CollectionUtil.isNotEmpty(subProgramUsageReportVos) && ObjectUtil.isNotNull(subProgramUsageReportVos.get(0)) && subProgramUsageReportVos.get(0).getAvgTime() > 0) {
                                        double avgTime = subProgramUsageReportVos.get(0).getAvgTime();
                                        double l = avgTime / (1000 * 60);
                                        BigDecimal multiply = new BigDecimal(l).multiply(new BigDecimal(toolDemandPredictionParamVo.getNumber()));
                                        subProgramParamVo.setCollectTime(multiply);
                                    }
                                    //设置程序单条时长
                                    BigDecimal numberBd = new BigDecimal(toolDemandPredictionParamVo.getNumber());
                                    if (ObjectUtil.isNotNull(subProgramParamVo.getHandleTime())) {
                                        subProgramParamVo.setOneTime(subProgramParamVo.getHandleTime().multiply(numberBd));
                                    } else if (ObjectUtil.isNotNull(subProgramParamVo.getAvgTime())) {
                                        subProgramParamVo.setOneTime(subProgramParamVo.getAvgTime().multiply(numberBd));
                                    } else if (ObjectUtil.isNotNull(subProgramParamVo.getCollectTime())) {
                                        subProgramParamVo.setOneTime(subProgramParamVo.getCollectTime().multiply(numberBd));
                                    }
                                }
                                Map<String, List<SubProgramParamVo>> collect = subProgramEntityList
                                        .stream()
                                        .collect(Collectors.groupingBy(SubProgramParamVo::getToolCode));
                                //整合刀号和程序list的对应关系map
                                Map<String, List<String>> collect1 = collect.entrySet()
                                        .stream()
                                        .collect(Collectors.toMap(Map.Entry::getKey, value -> value
                                                .getValue()
                                                .stream()
                                                .map(SubProgramParamVo::getName)
                                                .collect(Collectors.toList())));
                                //整合刀号时长
                                Map<String, Double> collect2 = collect.entrySet()
                                        .stream()
                                        .collect(Collectors.toMap(Map.Entry::getKey, value -> value
                                                .getValue()
                                                .stream()
                                                .mapToDouble(subprogramVo -> subprogramVo.getOneTime().doubleValue())
                                                .sum()));
                                subProgramEntityList = subProgramEntityList
                                        .stream()
                                        .filter(distinctByKey(SubProgramParamVo::getToolCode))
                                        .collect(Collectors.toList());
                                subProgramEntityList.forEach(subProgramParamVo -> {
                                    //设置整合后的程序列表
                                    subProgramParamVo.setSubPrograms(collect1.getOrDefault(subProgramParamVo.getToolCode(), new ArrayList<>()));
                                    //设置整合后的计算时长
                                    subProgramParamVo.setIntegrationTime(BigDecimal.valueOf(collect2.get(subProgramParamVo.getToolCode())));
                                });
                            }
                        }
                        toolDemandPredictionParamVo.setSubProgramParamVoList(subProgramEntityList);
                        toolDemandPredictionParamVo.setSingleTime(toolDemandPredictionParamVo.getHandleTime().divide(new BigDecimal(subProgramEntityList.size()), BigDecimal.ROUND_CEILING));
                        List<ToolDemandPredictionVo> toolDemandPredictionVos = buildToolDemandPredictionVoReload(toolDemandPredictionParamVo);
                        toolList.addAll(Objects.requireNonNull(toolDemandPredictionVos));
                    }
                }
            }
            buildStatus(toolList);
            if (CollectionUtil.isNotEmpty(toolList)) {
                toolList.forEach(toolDemandPredictionVo -> {
                    if (ObjectUtil.isNull(toolDemandPredictionVo.getStatus())) {
                        toolDemandPredictionVo.setStatus(CommonConstant.NOT_SATISFIED_CONST);
                    }
                });
            }
            if (flag) {
                //查所有
                toolList = toolList
                        .stream()
                        .filter(toolDemandPredictionVo -> ObjectUtil.isNotNull(toolDemandPredictionVo.getStatus()) && toolDemandPredictionVo.getStatus().equals(CommonConstant.NOT_SATISFIED_CONST) || ObjectUtil.isNotNull(toolDemandPredictionVo.getStatus()) && toolDemandPredictionVo.getStatus().equals("3"))
                        .collect(Collectors.toList());
            }
            if (CollectionUtil.isNotEmpty(toolList)) {
                //根据状态排序
                toolList = toolList
                        .stream()
                        .sorted(Comparator.comparing(ToolDemandPredictionVo::getStatus))
                        .collect(Collectors.toList());
            }
            //工单号和工序号筛选不为空 则过滤
            if (CollectionUtil.isNotEmpty(qryTaskIds)) {
                //查询指定工单号下所有工序的数据
                toolList = toolList
                        .stream()
                        .filter(toolDemandPredictionVo -> qryTaskIds.contains(toolDemandPredictionVo.getTaskId()))
                        .collect(Collectors.toList());
                if (CollectionUtil.isNotEmpty(qrySeqs)) {
                    //查询指定工单号下指定工序号的数据
                    toolList = toolList
                            .stream()
                            .filter(toolDemandPredictionVo -> qrySeqs.contains(toolDemandPredictionVo.getSeq()))
                            .collect(Collectors.toList());
                }
            }

            List<ToolDemandPredictionVo> pageList = new ArrayList<>();
            List<TaskIdGroupVo> taskIdGroupVos = new ArrayList<>();
            retMap.put("groupList", taskIdGroupVos);
            if (CollectionUtil.isNotEmpty(toolList)) {
                //结果分组工单号，以及工单号对应的工序序列号
                List<String> taskIds = toolList
                        .stream()
                        .map(ToolDemandPredictionVo::getTaskId).distinct()
                        .collect(Collectors.toList());
                if (CollectionUtil.isNotEmpty(taskIds)) {
                    List<ToolDemandPredictionVo> groupList = new ArrayList<>();
                    for (String taskId : taskIds) {
                        TaskIdGroupVo taskIdGroupVo = new TaskIdGroupVo();
                        //循环分组工单号，并印射工单号对应的工序号数组
                        groupList = toolList.stream()
                                .filter(toolDemandPredictionVo ->
                                        ObjectUtil.isNotNull(toolDemandPredictionVo.getTaskId()) && taskId.equals(toolDemandPredictionVo.getTaskId()))
                                .collect(Collectors.toList());
                        taskIdGroupVo.setTaskId(taskId);
                        if (CollectionUtil.isNotEmpty(groupList)) {
                            List<Integer> seqs = groupList.stream()
                                    .map(ToolDemandPredictionVo::getSeq)
                                    .distinct()
                                    .collect(Collectors.toList());
                            taskIdGroupVo.setSeqs(seqs);
                        } else {
                            taskIdGroupVo.setSeqs(new ArrayList<>());
                        }
                        taskIdGroupVos.add(taskIdGroupVo);
                    }
                }
                retMap.put("groupList", taskIdGroupVos);
                //toolList = toolList.stream().sorted(Comparator.comparing(ToolDemandPredictionVo::getToolCode)).collect(Collectors.toList());
                pageList = CommonUtil.pageList(toolList, pageNum, pageSize);

                //设置排班人员信息
                if (CollectionUtil.isNotEmpty(pageList)) {
                    pageList.forEach(toolDemandPredictionVo -> {
                        //toolDemandPredictionVo.setEmployeeName(machineToolTaskRespository.selectCurrentEmployeeTask(toolDemandPredictionVo.getMachineToolName() , new Date()));
                    });
                }
            }
            retMap.put("toolList", pageList);
            retMap.put("total", toolList.size());
        } else {
            //分配的任务未关联子程序
            retMap.put("groupList", new ArrayList<>());
            retMap.put("toolList", new ArrayList<>());
            retMap.put("total", 0);
        }
    }

    private void getTaskUnmetTool(Integer pageNum, Integer pageSize, List<Integer> idList, Map<String, Object> retMap, Boolean flag, Boolean flag2) {
        if (CollectionUtil.isEmpty(idList)) {
            //工单未分配任务
            retMap.put("toolList", new ArrayList<>());
            retMap.put("total", 0);
            return;
        }
        //获取该预测任务的前置任务清单
        List<MachineToolTaskEntity> preTaskList = new ArrayList<>();
        Map<String, Double> preToolUsageTimeMap = new HashMap<>();
        List<MachineToolTaskEntity> machineToolTaskEntities = machineToolTaskRespository.selectListById(idList);
        if (CollectionUtil.isNotEmpty(machineToolTaskEntities)) {
            MachineToolTaskEntity machineToolTaskEntity = machineToolTaskEntities.get(0);
            //当前机床该任务是否有前置任务
            if (ObjectUtil.isNull(machineToolTaskEntity.getActualStartTime())) {
                //只在当前任务未开始时预测
                preTaskList = machineToolTaskRespository.selectPreTask(new Date(), machineToolTaskEntity.getMachineToolId(), machineToolTaskEntity.getStartTime());
            }
        }

        if (CollectionUtil.isNotEmpty(preTaskList)) {
            MachineToolTaskEntity machineToolTaskEntity = preTaskList.get(0);
            //判断第一个任务是否已经开始
            if (ObjectUtil.isNotNull(machineToolTaskEntity) && ObjectUtil.isNotNull(machineToolTaskEntity.getActualStartTime())) {
                //是已经开始 单独处理
                getToolParamList(preTaskList, preToolUsageTimeMap, machineToolTaskEntity, 1);
                preTaskList.remove(machineToolTaskEntity);
            }
            getToolParamList(preTaskList, preToolUsageTimeMap, machineToolTaskEntity, 0);
        }

        //获取刀具清单
        List<ToolDemandPredictionParamVo> toolParamList = orderRespository.getToolDemandPredictionList(idList);
        //刀具清单列表不为空(新建工单快照程序信息逻辑为：工序未关联主程序就不持久化到工单程序快照表中)
        if (CollectionUtil.isNotEmpty(toolParamList)) {
            //过滤掉未关联子程序的
            List<ToolDemandPredictionVo> toolList = new ArrayList<>();
            for (ToolDemandPredictionParamVo toolDemandPredictionParamVo : toolParamList) {
                if (ObjectUtil.isNotNull(toolDemandPredictionParamVo.getSubProgramParam())) {
                    List<ToolDemandPredictionVo> toolDemandPredictionVos = buildToolDemandPredictionVo(toolDemandPredictionParamVo);
                    toolList.addAll(Objects.requireNonNull(toolDemandPredictionVos));
                } else {
                    //去产品表找程序数据
                    List<SubProgramParamVo> subProgramEntityList = orderRespository.selectProgram(toolDemandPredictionParamVo.getTaskId(), toolDemandPredictionParamVo.getSeq());
                    //计算单个程序平均耗时
                    if (CollectionUtil.isNotEmpty(subProgramEntityList)) {
                        if (ObjectUtil.isNotNull(flag2) && flag2) {
                            //需要整合
                            if (CollectionUtil.isNotEmpty(subProgramEntityList)) {
                                BigDecimal subProgramListSize = new BigDecimal(subProgramEntityList.size());
                                subProgramEntityList.forEach(subProgramParamVo -> {
                                    //获取平均时间
                                    subProgramParamVo.setAvgTime(toolDemandPredictionParamVo.getHandleTime().divide(subProgramListSize, BigDecimal.ROUND_CEILING));
                                    //获取反填时间
                                    List<SubProgramUsageReportVo> subProgramUsageReportVos = programDurationTimeRepository.selectByProgramName(subProgramParamVo.getName());
                                    if (CollectionUtil.isNotEmpty(subProgramUsageReportVos) && ObjectUtil.isNotNull(subProgramUsageReportVos.get(0)) && subProgramUsageReportVos.get(0).getAvgTime() > 0) {
                                        double avgTime = subProgramUsageReportVos.get(0).getAvgTime();
                                        double l = avgTime / (1000 * 60);
                                        BigDecimal multiply = new BigDecimal(l).multiply(new BigDecimal(toolDemandPredictionParamVo.getNumber()));
                                        subProgramParamVo.setCollectTime(multiply);
                                    }
                                    //设置程序单条时长
                                    if (ObjectUtil.isNotNull(subProgramParamVo.getHandleTime())) {
                                        subProgramParamVo.setOneTime(subProgramParamVo.getHandleTime());
                                    } else if (ObjectUtil.isNotNull(subProgramParamVo.getAvgTime())) {
                                        subProgramParamVo.setOneTime(subProgramParamVo.getAvgTime());
                                    } else if (ObjectUtil.isNotNull(subProgramParamVo.getCollectTime())) {
                                        subProgramParamVo.setOneTime(subProgramParamVo.getCollectTime());
                                    }
                                });
                                Map<String, List<SubProgramParamVo>> collect = subProgramEntityList
                                        .stream()
                                        .collect(Collectors.groupingBy(SubProgramParamVo::getToolCode));
                                //整合刀号和程序list的对应关系map
                                Map<String, List<String>> collect1 = collect.entrySet()
                                        .stream()
                                        .collect(Collectors.toMap(Map.Entry::getKey, value -> value
                                                .getValue()
                                                .stream()
                                                .map(SubProgramParamVo::getName)
                                                .collect(Collectors.toList())));
                                //整合刀号时长
                                Map<String, Double> collect2 = collect.entrySet()
                                        .stream()
                                        .collect(Collectors.toMap(Map.Entry::getKey, value -> value
                                                .getValue()
                                                .stream()
                                                .mapToDouble(subprogramVo -> subprogramVo.getOneTime().doubleValue())
                                                .sum()));
                                subProgramEntityList = subProgramEntityList
                                        .stream()
                                        .filter(distinctByKey(SubProgramParamVo::getToolCode))
                                        .collect(Collectors.toList());
                                subProgramEntityList.forEach(subProgramParamVo -> {
                                    //设置整合后的程序列表
                                    subProgramParamVo.setSubPrograms(collect1.getOrDefault(subProgramParamVo.getToolCode(), new ArrayList<>()));
                                    //设置整合后的计算时长
                                    subProgramParamVo.setIntegrationTime(BigDecimal.valueOf(collect2.get(subProgramParamVo.getToolCode())));
                                });
                            }
                        }
                        toolDemandPredictionParamVo.setSubProgramParamVoList(subProgramEntityList);
                        toolDemandPredictionParamVo.setSingleTime(toolDemandPredictionParamVo.getHandleTime().divide(new BigDecimal(subProgramEntityList.size()), BigDecimal.ROUND_CEILING));
                        List<ToolDemandPredictionVo> toolDemandPredictionVos = buildToolDemandPredictionVoReload(toolDemandPredictionParamVo);
                        toolList.addAll(Objects.requireNonNull(toolDemandPredictionVos));
                    }
                }
            }
            buildTaskStatus(toolList, preToolUsageTimeMap);
            if (flag) {
                //查所有
                toolList = toolList.stream().filter(toolDemandPredictionVo -> ObjectUtil.isNotNull(toolDemandPredictionVo.getStatus()) && toolDemandPredictionVo.getStatus().equals(CommonConstant.NOT_SATISFIED_CONST)).collect(Collectors.toList());
            }

            List<ToolDemandPredictionVo> pageList = new ArrayList<>();

            pageList = CommonUtil.pageList(toolList, pageNum, pageSize);
            retMap.put("toolList", pageList);
            retMap.put("total", toolList.size());
        } else {
            //分配的任务未关联子程序
            retMap.put("groupList", new ArrayList<>());
            retMap.put("toolList", new ArrayList<>());
            retMap.put("total", 0);
        }
    }

    private void getToolParamList(List<MachineToolTaskEntity> preTaskList, Map<String, Double> preToolUsageTimeMap, MachineToolTaskEntity machineToolTaskEntity, Integer flag) {
        List<ToolDemandPredictionParamVo> toolParamList = orderRespository.getToolDemandPredictionList(preTaskList.stream().map(MachineToolTaskEntity::getId).collect(Collectors.toList()));
        if (CollectionUtil.isNotEmpty(toolParamList)) {
            //过滤掉未关联子程序的
            List<ToolDemandPredictionVo> toolList = new ArrayList<>();
            for (ToolDemandPredictionParamVo toolDemandPredictionParamVo : toolParamList) {
                if (ObjectUtil.isNotNull(toolDemandPredictionParamVo.getSubProgramParam())) {
                    List<ToolDemandPredictionVo> toolDemandPredictionVos = buildToolDemandPredictionVo(toolDemandPredictionParamVo);
                    toolList.addAll(Objects.requireNonNull(toolDemandPredictionVos));
                } else {
                    //去产品表找程序数据
                    List<SubProgramParamVo> subProgramEntityList = orderRespository.selectProgram(toolDemandPredictionParamVo.getTaskId(), toolDemandPredictionParamVo.getSeq());
                    //计算单个程序平均耗时
                    if (CollectionUtil.isNotEmpty(subProgramEntityList)) {
                        toolDemandPredictionParamVo.setSubProgramParamVoList(subProgramEntityList);
                        if (flag == 1) {
                            //计算出已运行的任务时长 求出剩下需要运行的时长
                            long between = DateUtil.between(machineToolTaskEntity.getStartTime(), new Date(), DateUnit.HOUR);
                            toolDemandPredictionParamVo.setHandleTime(toolDemandPredictionParamVo.getHandleTime().subtract(new BigDecimal(between).multiply(new BigDecimal(toolDemandPredictionParamVo.getNumber()))).compareTo(BigDecimal.ZERO) > 0 ?
                                    toolDemandPredictionParamVo.getHandleTime().subtract(new BigDecimal(between).multiply(new BigDecimal(toolDemandPredictionParamVo.getNumber()))) : toolDemandPredictionParamVo.getHandleTime());

                        }
                        toolDemandPredictionParamVo.setSingleTime(toolDemandPredictionParamVo.getHandleTime().divide(new BigDecimal(subProgramEntityList.size()), BigDecimal.ROUND_CEILING));
                        //获取每个任务消耗刀具的时间
                        buildTaskToolUsageTime(toolDemandPredictionParamVo, preToolUsageTimeMap);
                    }
                }
            }
        }
    }

    private void buildTaskToolUsageTime(ToolDemandPredictionParamVo toolParam, Map<String, Double> preToolUsageTimeMap) {
        if (CollectionUtil.isNotEmpty(toolParam.getSubProgramParamVoList())) {
            toolParam.getSubProgramParamVoList()
                    .forEach(subProgramParamVo -> {
                        String toolCode = subProgramParamVo.getToolCode();
                        //不整合计算
//                            List<SubProgramUsageReportVo> subProgramUsageReportVos = programDurationTimeRepository.selectByProgramName(subProgramParamVo.getName());
//                            if(CollectionUtil.isNotEmpty(subProgramUsageReportVos) && ObjectUtil.isNotNull(subProgramUsageReportVos.get(0)) &&subProgramUsageReportVos.get(0).getAvgTime() >0){
//                                double avgTime = subProgramUsageReportVos.get(0).getAvgTime();
//                                double l = avgTime / (1000 * 60);
//                                BigDecimal multiply = new BigDecimal(l).multiply(new BigDecimal(toolParam.getNumber()));
//                                toolDemandPredictionVo.setSingleTime(multiply);
//                            }else {
//                                toolDemandPredictionVo.setSingleTime(ObjectUtil.isNotNull(subProgramParamVo.getHandleTime()) ? subProgramParamVo.getHandleTime().multiply(new BigDecimal(toolParam.getNumber())) : toolParam.getSingleTime());
//                            }
                        BigDecimal singleTime = ObjectUtil.isNotNull(subProgramParamVo.getHandleTime()) ?
                                subProgramParamVo.getHandleTime().multiply(new BigDecimal(toolParam.getNumber())) : toolParam.getSingleTime();
                        preToolUsageTimeMap.put(toolCode, preToolUsageTimeMap.getOrDefault(toolCode, 0.0) + singleTime.doubleValue());
                    });
        }
    }

    static <T> Predicate<T> distinctByKey(Function<? super T, ?> keyExtractor) {
        Map<Object, Boolean> seen = new ConcurrentHashMap<>();
        return t -> seen.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE) == null;
    }

    private List<ToolDemandPredictionVo> buildToolDemandPredictionVo(ToolDemandPredictionParamVo toolParam) {
        List<ToolDemandPredictionVo> singleToolList = new ArrayList<>();
        JSONArray.parseArray(toolParam.getSubProgramParam(), SubProgramParamVo.class)
                .forEach(subProgramParamVo -> {
                    ToolDemandPredictionVo toolDemandPredictionVo = new ToolDemandPredictionVo();
                    toolDemandPredictionVo.setId(toolParam.getId());
                    toolDemandPredictionVo.setTaskId(toolParam.getTaskId());
                    toolDemandPredictionVo.setMachineToolId(toolParam.getMachineToolId());
                    toolDemandPredictionVo.setMachineToolName(toolParam.getMachineToolName());
                    toolDemandPredictionVo.setProcessCraftName(toolParam.getProcessCraftName());
                    toolDemandPredictionVo.setEmployeeId(toolParam.getEmployeeId());
                    toolDemandPredictionVo.setEmployeeName(toolParam.getEmployeeName());
                    toolDemandPredictionVo.setSubProgramName(subProgramParamVo.getName());
                    toolDemandPredictionVo.setCreateTime(toolParam.getCreateTime());
                    toolDemandPredictionVo.setFinishTime(toolParam.getFinishTime());
                    toolDemandPredictionVo.setNumber(toolParam.getNumber());
                    BeanUtils.copyProperties(subProgramParamVo, toolDemandPredictionVo);
                    singleToolList.add(toolDemandPredictionVo);
                });
        return singleToolList;
    }

    private List<ToolDemandPredictionVo> buildToolDemandPredictionVoReload(ToolDemandPredictionParamVo toolParam) {
        List<ToolDemandPredictionVo> singleToolList = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(toolParam.getSubProgramParamVoList())) {
            toolParam.getSubProgramParamVoList()
                    .forEach(subProgramParamVo -> {
                        ToolDemandPredictionVo toolDemandPredictionVo = new ToolDemandPredictionVo();
                        toolDemandPredictionVo.setId(toolParam.getId());
                        toolDemandPredictionVo.setTaskId(toolParam.getTaskId());
                        toolDemandPredictionVo.setMachineToolId(toolParam.getMachineToolId());
                        toolDemandPredictionVo.setMachineToolName(toolParam.getMachineToolName());
                        toolDemandPredictionVo.setProcessCraftName(toolParam.getProcessCraftName());
                        toolDemandPredictionVo.setEmployeeId(toolParam.getEmployeeId());
                        toolDemandPredictionVo.setEmployeeName(toolParam.getEmployeeName());
                        toolDemandPredictionVo.setSubProgramName(subProgramParamVo.getName());
                        toolDemandPredictionVo.setCreateTime(toolParam.getCreateTime());
                        toolDemandPredictionVo.setFinishTime(toolParam.getFinishTime());
                        toolDemandPredictionVo.setSubprograms(subProgramParamVo.getSubPrograms());
                        if (ObjectUtil.isNotNull(subProgramParamVo.getIntegrationTime())) {
                            //整合计算
                            toolDemandPredictionVo.setSingleTime(subProgramParamVo.getIntegrationTime());
                        } else {
//                            //不整合计算
//                            List<SubProgramUsageReportVo> subProgramUsageReportVos = programDurationTimeRepository.selectByProgramName(subProgramParamVo.getName());
//                            if(CollectionUtil.isNotEmpty(subProgramUsageReportVos) && ObjectUtil.isNotNull(subProgramUsageReportVos.get(0)) &&subProgramUsageReportVos.get(0).getAvgTime() >0){
//                                double avgTime = subProgramUsageReportVos.get(0).getAvgTime();
//                                double l = avgTime / (1000 * 60);
//                                BigDecimal multiply = new BigDecimal(l).multiply(new BigDecimal(toolParam.getNumber()));
//                                toolDemandPredictionVo.setSingleTime(multiply);
//                            }else {
//                                toolDemandPredictionVo.setSingleTime(ObjectUtil.isNotNull(subProgramParamVo.getHandleTime()) ? subProgramParamVo.getHandleTime().multiply(new BigDecimal(toolParam.getNumber())) : toolParam.getSingleTime());
//                            }
                            toolDemandPredictionVo.setSingleTime(ObjectUtil.isNotNull(subProgramParamVo.getHandleTime()) ? subProgramParamVo.getHandleTime().multiply(new BigDecimal(toolParam.getNumber())) : toolParam.getSingleTime());
                        }
                        toolDemandPredictionVo.setMaterialNo(toolParam.getMaterialNo());
                        toolDemandPredictionVo.setProductionNum(toolParam.getProductionNum());
                        BeanUtils.copyProperties(subProgramParamVo, toolDemandPredictionVo);
                        singleToolList.add(toolDemandPredictionVo);
                    });
        }
        return singleToolList;
    }

//    private BigDecimal getProgramTime(String programName){
//        List<SubProgramUsageReportVo> subProgramUsageReportVos = programDurationTimeRepository.selectByProgramName(programName);
//        if(CollectionUtil.isNotEmpty(subProgramUsageReportVos) && ObjectUtil.isNotNull(subProgramUsageReportVos.get(0)) &&subProgramUsageReportVos.get(0).getAvgTime() >0){
//            double avgTime = subProgramUsageReportVos.get(0).getAvgTime();
//            double l = avgTime / (1000 * 60);
//            return new BigDecimal(l);
//        }
//        return new BigDecimal(0);
//    }

    private List<ToolDemandPredictionVo> buildToolDemandPredictionVoReload1(ToolDemandPredictionParamVo toolParam, Boolean flag) {
        List<ToolDemandPredictionVo> singleToolList = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(toolParam.getSubProgramParamVoList())) {
            toolParam.getSubProgramParamVoList()
                    .forEach(subProgramParamVo -> {
                        ToolDemandPredictionVo toolDemandPredictionVo = new ToolDemandPredictionVo();
                        toolDemandPredictionVo.setId(toolParam.getId());
                        toolDemandPredictionVo.setTaskId(toolParam.getTaskId());
                        toolDemandPredictionVo.setMachineToolId(toolParam.getMachineToolId());
                        toolDemandPredictionVo.setMachineToolName(toolParam.getMachineToolName());
                        toolDemandPredictionVo.setProcessCraftName(toolParam.getProcessCraftName());
                        toolDemandPredictionVo.setEmployeeId(toolParam.getEmployeeId());
                        toolDemandPredictionVo.setEmployeeName(toolParam.getEmployeeName());
                        toolDemandPredictionVo.setSubProgramName(subProgramParamVo.getName());
                        toolDemandPredictionVo.setCreateTime(toolParam.getCreateTime());
                        toolDemandPredictionVo.setFinishTime(toolParam.getFinishTime());
                        if (flag) {
                            List<SubProgramUsageReportVo> subProgramUsageReportVos = programDurationTimeRepository.selectByProgramName(subProgramParamVo.getName());
                            //SubProgramUsageReportVo subProgramUsageReportVo = machineToolStatusRepository.subProgramUsageReportReload(subProgramParamVo.getName());
                            if (CollectionUtil.isNotEmpty(subProgramUsageReportVos) && ObjectUtil.isNotNull(subProgramUsageReportVos.get(0)) && subProgramUsageReportVos.get(0).getAvgTime() > 0) {
                                double avgTime = subProgramUsageReportVos.get(0).getAvgTime();
                                double l = avgTime / (1000 * 60);
                                BigDecimal multiply = new BigDecimal(l).multiply(new BigDecimal(toolParam.getNumber()));
                                toolDemandPredictionVo.setSingleTime(multiply);
                            } else {
                                toolDemandPredictionVo.setSingleTime(ObjectUtil.isNotNull(subProgramParamVo.getHandleTime()) ? subProgramParamVo.getHandleTime().multiply(new BigDecimal(toolParam.getNumber())) : toolParam.getSingleTime());
                            }
                        } else {
                            toolDemandPredictionVo.setSingleTime(toolParam.getSingleTime());
                        }
                        toolDemandPredictionVo.setMaterialNo(toolParam.getMaterialNo());
                        toolDemandPredictionVo.setProductionNum(toolParam.getProductionNum());
                        BeanUtils.copyProperties(subProgramParamVo, toolDemandPredictionVo);
                        singleToolList.add(toolDemandPredictionVo);
                    });
        }
        return singleToolList;
    }

    private void setStatusByCondition(ToolDemandPredictionVo toolDemandPredictionVo, Double machineToolLife, Double machineTimeUsage, Double backToolLife, Double backRemaining, Map<String, Double> sumMap) {
        double singleTime = sumMap.get(toolDemandPredictionVo.getGroupId());
        double machineRemainingLife = machineToolLife - machineTimeUsage;
        double requireTime = singleTime - machineRemainingLife - backRemaining;
        if (machineRemainingLife >= singleTime) {
            //机床刀具剩余寿命大于完成任务需要寿命
            //已满足
            toolDemandPredictionVo.setStatus(CommonConstant.SATISFIED_CONST);
            toolDemandPredictionVo.setPredictionNumber(0);
        } else {
            //区分未满足还是已备刀
            if (machineRemainingLife + backRemaining >= singleTime) {
                //已备刀
                toolDemandPredictionVo.setStatus("2");
                toolDemandPredictionVo.setPredictionNumber(0);
            } else {
                //未满足
                //区分未满足还是已备刀部分
                if (backRemaining - 0.0 > 0) {
                    toolDemandPredictionVo.setStatus("3");
                    toolDemandPredictionVo.setPredictionNumber((int) Math.ceil(requireTime / getDefaultLife(toolDemandPredictionVo.getToolCode())));
                }else{
                    toolDemandPredictionVo.setStatus(CommonConstant.NOT_SATISFIED_CONST);
                    toolDemandPredictionVo.setPredictionNumber((int) Math.ceil(requireTime / getDefaultLife(toolDemandPredictionVo.getToolCode())));
                }
            }
        }

    }


    private void countBackupToolNumber(Map<String, Double> sumMap, ToolDemandPredictionVo toolDemandPredictionVo) {
        List<ToolPartEntity> toolPartEntity = warehouseRespository.selectByBackUpStatus(toolDemandPredictionVo.getId(), toolDemandPredictionVo.getToolCode(), toolDemandPredictionVo.getSubProgramName());
        //计算备刀寿命
        double toolUsageTime = toolPartEntity
                .stream()
                .mapToDouble(toolPart -> Double.parseDouble(toolPart.getRemainingLife().substring(0, toolPart.getRemainingLife().length() - 1)))
                .sum();
        double toolLifeDouble = toolPartEntity
                .stream()
                .mapToDouble(toolPart -> Double.parseDouble(toolPart.getLife().substring(0, toolPart.getLife().length() - 1)))
                .sum();
        toolDemandPredictionVo.setLife(getDefaultLife(toolDemandPredictionVo.getToolCode()));
        int requireNumber = countNumber(ObjectUtil.isNotNull(toolLifeDouble) ? toolLifeDouble : getDefaultLife(toolDemandPredictionVo.getToolCode()),
                ObjectUtil.isNotNull(toolUsageTime) ? toolUsageTime : 0.00,
                BigDecimal.valueOf(sumMap.get(toolDemandPredictionVo.getToolCode())));
        if (requireNumber > 0) {
            //状态为未满足，备刀数量为条件值
            toolDemandPredictionVo.setStatus(CommonConstant.NOT_SATISFIED_CONST);
            toolDemandPredictionVo.setPredictionNumber(requireNumber);
        } else {
            //状态为已备刀
            toolDemandPredictionVo.setStatus("2");
            toolDemandPredictionVo.setPredictionNumber(requireNumber);
        }
        if (CollectionUtil.isNotEmpty(toolPartEntity)) {
            toolDemandPredictionVo.setLocationId(toolPartEntity.stream().map(ToolPartEntity::getInventoryLocationId).collect(Collectors.toList()));
            toolDemandPredictionVo.setLocationName(toolPartEntity.stream().map(this::mapToLocationNum).collect(Collectors.toList()));
        }
        toolDemandPredictionVo.setLife(ObjectUtil.isNotNull(toolLifeDouble) ? toolLifeDouble : getDefaultLife(toolDemandPredictionVo.getToolCode()));
    }

    private String mapToLocationNum(ToolPartEntity toolPartEntity) {
        return inventoryLocationRespository.queryLocationNumById(toolPartEntity.getInventoryLocationId());
    }

    private void buildStatusReport(List<ToolDemandPredictionVo> toolList) {
        //校验如果分配的工序任务全未管理子程序 则直接返回
        if (CollectionUtil.isEmpty(toolList)) {
            return;
        }
//        //初始化snMap
//        initSnFlagMap();
//        initToolParamMap();
        //设置刀具清单状态(机床采集数据设置)
        toolList.forEach(toolDemandPredictionVo -> {
            //未满足
            countReportNumber(toolDemandPredictionVo);
            toolDemandPredictionVo.setLife(getDefaultLife(toolDemandPredictionVo.getToolCode()));
        });
    }

    private void countReportNumber(ToolDemandPredictionVo toolDemandPredictionVo) {
        toolDemandPredictionVo.setStatus(CommonConstant.NOT_SATISFIED_CONST);
        QueryWrapper<ToolLifeEntity> wrapper = new QueryWrapper<>();
        wrapper.eq("classify", toolDemandPredictionVo.getToolCode());
        ToolLifeEntity toolLifeEntity = toolLifeMapper.selectOne(wrapper);
        if (ObjectUtil.isNotNull(toolLifeEntity)) {
            Double toolLife = toolLifeEntity.getLife().doubleValue();
            toolDemandPredictionVo.setLife(toolLife);
            toolDemandPredictionVo.setPredictionNumber((int) Math.ceil(toolDemandPredictionVo.getSingleTime().doubleValue() / toolLife));
        } else {
            Double toolLife = 60.0;
            toolDemandPredictionVo.setLife(getDefaultLife(toolDemandPredictionVo.getToolCode()));
            toolDemandPredictionVo.setPredictionNumber((int) Math.ceil(toolDemandPredictionVo.getSingleTime().doubleValue() / toolLife));
        }
    }

    private void countGroupNumber(ToolDemandPredictionVo toolDemandPredictionVo, double countTime) {
        toolDemandPredictionVo.setStatus(CommonConstant.NOT_SATISFIED_CONST);
        QueryWrapper<ToolLifeEntity> wrapper = new QueryWrapper<>();
        wrapper.eq("classify", toolDemandPredictionVo.getToolCode());
        ToolLifeEntity toolLifeEntity = toolLifeMapper.selectOne(wrapper);
        if (ObjectUtil.isNotNull(toolLifeEntity)) {
            Double toolLife = toolLifeEntity.getLife().doubleValue();
            toolDemandPredictionVo.setLife(toolLife);
            toolDemandPredictionVo.setPredictionNumber((int) Math.ceil(countTime / toolLife));
            toolDemandPredictionVo.setMachineToolExistNumber(0);
            toolDemandPredictionVo.setMachineToolExistLife(0.0);
        } else {
            Double toolLife = 60.0;
            toolDemandPredictionVo.setLife(getDefaultLife(toolDemandPredictionVo.getToolCode()));
            toolDemandPredictionVo.setPredictionNumber((int) Math.ceil(countTime / toolLife));
            toolDemandPredictionVo.setMachineToolExistNumber(0);
            toolDemandPredictionVo.setMachineToolExistLife(0.0);
        }
    }

    /**
     * 人员需求预测重载方法
     *
     * @param toolList
     */
    private void buildStatusReload(List<ToolDemandPredictionVo> toolList) {
        //校验如果分配的工序任务全未管理子程序 则直接返回
        if (CollectionUtil.isEmpty(toolList)) {
            return;
        }
        initSnFlagMap();
        initToolParamMap();

        //分组查询机床的刀具列表
        //Map<Integer , List<IncBoxParamVo>>  machineToolParamMap = queryToolParamBySnCode(toolList);
        MachineToolParamVo machineToolParamVo = queryToolParamBySnCode(toolList);

        BackupToolLifeVo backupToolLifeVo = queryBackupToolMapReload(toolList);

        //设置刀具清单状态(机床采集数据设置)
        Map<String, Integer> countMap = toolList.stream().collect(Collectors.toMap(ToolDemandPredictionVo::getToolCode, value -> 1, Integer::sum));
        Map<String, List<ToolDemandPredictionVo>> groupByMap = toolList.stream().collect(Collectors.groupingBy(ToolDemandPredictionVo::getToolCode));
        Map<String, Double> sumMap = groupByMap
                .entrySet()
                .stream()
                .collect(Collectors.toMap(Map.Entry::getKey, value -> value.getValue()
                        .stream()
                        .mapToDouble(toolDemandPredictionVo -> toolDemandPredictionVo.getSingleTime().doubleValue()).sum()));
        //设置刀具清单状态(机床采集数据设置)
        toolList.forEach(toolDemandPredictionVo -> {
            toolDemandPredictionVo.setCount(countMap.get(toolDemandPredictionVo.getToolCode()));
            toolDemandPredictionVo.setCountTime(sumMap.get(toolDemandPredictionVo.getToolCode()));
            Map<Integer, List<IncBoxParamVo>> machineToolParamMap = machineToolParamVo.getMachineToolParamMap();

            Integer machineToolId = toolDemandPredictionVo.getMachineToolId();
            List<IncBoxParamVo> incBoxParamVos = toolParamsMap.get(toolDemandPredictionVo.getMachineToolName());

            if (CollectionUtil.isNotEmpty(incBoxParamVos)) {
                String toolName = toolDemandPredictionVo.getToolCode().replaceFirst(".", "");
                Map<String, Double> sumToolLifeMap = machineToolParamVo.getMachineSumToolLifeMap().getOrDefault(machineToolId, new HashMap<>());

                Map<String, Double> sumTimeUsageMap = machineToolParamVo.getMachineSumTimeUsageMap().getOrDefault(machineToolId, new HashMap<>());

                Map<String, Integer> countMachineToolNoMap = machineToolParamVo.getCountMachineToolNoMap().getOrDefault(machineToolId, new HashMap<>());
                toolDemandPredictionVo.setMachineToolExistLife(sumToolLifeMap.getOrDefault(toolName, 0.0) - sumTimeUsageMap.getOrDefault(toolName, 0.0));
                toolDemandPredictionVo.setMachineToolExistNumber(countMachineToolNoMap.getOrDefault(toolName, 0));
                //计算备刀寿命值
                String key = toolDemandPredictionVo.getId() + toolDemandPredictionVo.getToolCode();
                Map<String, Double> backupRemainingLifeMap = backupToolLifeVo.getBackupRemainingLifeMap();
                Map<String, Double> backupToolLifeMap = backupToolLifeVo.getBackupToolLifeMap();
                double backToolLife = backupToolLifeMap.getOrDefault(key, 0.0);
                double backRemainingLife = backupRemainingLifeMap.getOrDefault(key, 0.0);
                toolDemandPredictionVo.setBackupLife(backToolLife);
                toolDemandPredictionVo.setBackupTimeUsage(backRemainingLife);

                Map<String, List<String>> backupLocationMap = backupToolLifeVo.getBackupLocationMap();
                toolDemandPredictionVo.setLocationName(backupLocationMap.getOrDefault(key, new ArrayList<>()));

                toolDemandPredictionVo.setLife(getDefaultLife(toolDemandPredictionVo.getToolCode()));
                setStatusByCondition(toolDemandPredictionVo
                        , sumToolLifeMap.getOrDefault(toolName, 0.0)
                        , sumTimeUsageMap.getOrDefault(toolName, 0.0)
                        , backToolLife
                        , backRemainingLife
                        , sumMap);
            }
        });

    }


    private void buildStatus(List<ToolDemandPredictionVo> toolList) {
        //校验如果分配的工序任务全未管理子程序 则直接返回
        if (CollectionUtil.isEmpty(toolList)) {
            return;
        }
        //初始化snMap
        initSnFlagMap();
        initToolParamMap();

        //分组查询机床的刀具列表
        //Map<Integer , List<IncBoxParamVo>>  machineToolParamMap = queryToolParamBySnCode(toolList);
        MachineToolParamVo machineToolParamVo = queryToolParamBySnCode(toolList);

        BackupToolLifeVo backupToolLifeVo = queryBackupToolMapReload(toolList);

        //设置刀具清单状态(机床采集数据设置)
        Map<String, Integer> countMap = toolList
                .stream()
                .collect(Collectors.toMap(ToolDemandPredictionVo::getToolCode, value -> 1, Integer::sum));
        Map<String, List<ToolDemandPredictionVo>> groupIdByMap = toolList
                .stream()
                .collect(Collectors.groupingBy(ToolDemandPredictionVo::getGroupId));
        //计算每个任务对应刀号所需总时长
        Map<String, Double> sumMap = groupIdByMap
                .entrySet()
                .stream()
                .collect(Collectors.toMap(Map.Entry::getKey, value -> value.getValue()
                        .stream()
                        .mapToDouble(toolDemandPredictionVo -> toolDemandPredictionVo.getSingleTime().doubleValue()).sum()));
        if (CollectionUtil.isNotEmpty(groupIdByMap)) {
            List<ToolDemandPredictionVo> sortList = new ArrayList<>();
            groupIdByMap.forEach((k, v) -> {
                sortList.addAll(v);
            });
            toolList = sortList;
        }

        //查询寿命
        //刀具清单的刀具号List
        List<ToolDemandPredictionVo> distinctToolCodeList = toolList.stream().distinct().collect(Collectors.toList());
        Map<String, List<ToolLifeEntity>> groupByToolCodeMap = new HashMap<>();
        Map<String, List<ToolLifeEntity>> groupByToolModelMap = new HashMap<>();
        //需要根据零件计算寿命默认值的零件型号集合
        List<ToolDemandPredictionVo> toolModelList = new ArrayList<>();
        //最终构建的默认寿命map
        Map<String, Double> toolDefaultLifeMap = new HashMap<>();

        //将在配置表中配置了总成寿命的全部放入toolLifeConfigMap
        QueryWrapper<ToolLifeEntity> wrapper = new QueryWrapper<>();
        wrapper.in("classify", distinctToolCodeList.stream().map(ToolDemandPredictionVo::getToolCode).collect(Collectors.toList()));
        wrapper.eq("type_flag", 1);
        List<ToolLifeEntity> toolLifeEntities = toolLifeMapper.selectList(wrapper);
        if (CollectionUtil.isNotEmpty(toolLifeEntities)) {
            groupByToolCodeMap = toolLifeEntities
                    .stream()
                    .collect(Collectors.groupingBy(ToolLifeEntity::getClassify));
            for (ToolDemandPredictionVo toolDemandPredictionVo : distinctToolCodeList) {
                String toolCode = toolDemandPredictionVo.getToolCode();
                if (CollectionUtil.isEmpty(groupByToolCodeMap.getOrDefault(toolCode, new ArrayList<>()))) {
                    //这部分数据代表总成配置表中没有配置 需要根据零件来计算的
                    toolModelList.add(toolDemandPredictionVo);
                    continue;
                }
                toolDefaultLifeMap.put(toolCode, getDefaultLifeGroup(groupByToolCodeMap, toolCode));
            }
            //计算零件的配置寿命
            if (CollectionUtil.isNotEmpty(toolModelList)) {
                QueryWrapper<ToolLifeEntity> wrapper1 = new QueryWrapper<>();
                wrapper1.in("group_idnr", distinctToolCodeList
                        .stream()
                        .map(ToolDemandPredictionVo::getToolModel)
                        .collect(Collectors.toList()));
                wrapper1.eq("type_flag", 0);
                List<ToolLifeEntity> toolPartLifeEntities = toolLifeMapper.selectList(wrapper1);
                if(CollectionUtil.isNotEmpty(toolPartLifeEntities)){
                    groupByToolModelMap = toolPartLifeEntities
                            .stream()
                            .collect(Collectors.groupingBy(ToolLifeEntity::getGroupIdnr));
                }
                //设置寿命
                for (ToolDemandPredictionVo toolDemandPredictionVo : distinctToolCodeList) {
                    String toolModel = toolDemandPredictionVo.getToolModel();
                    if (CollectionUtil.isNotEmpty(groupByToolModelMap.getOrDefault(toolModel, new ArrayList<>()))) {
                        //这部分数据代表总成配置表中没有配置 需要根据零件来计算的
                        toolDefaultLifeMap.put(toolModel, getDefaultPartLifeGroup(groupByToolCodeMap, toolModel));
                    }
                }
            }
        }

        toolList.forEach(toolDemandPredictionVo -> {
            toolDemandPredictionVo.setCount(countMap.get(toolDemandPredictionVo.getToolCode()));
            toolDemandPredictionVo.setCountTime(sumMap.get(toolDemandPredictionVo.getGroupId()));
            Map<Integer, List<IncBoxParamVo>> machineToolParamMap = machineToolParamVo.getMachineToolParamMap();

            Integer machineToolId = toolDemandPredictionVo.getMachineToolId();
            List<IncBoxParamVo> incBoxParamVos = machineToolParamMap.getOrDefault(machineToolId, new ArrayList<>());

            String toolName = toolDemandPredictionVo.getToolCode().replaceFirst(".", "");
            Map<String, Double> sumToolLifeMap = machineToolParamVo.getMachineSumToolLifeMap().getOrDefault(machineToolId, new HashMap<>());

            Map<String, Double> sumTimeUsageMap = machineToolParamVo.getMachineSumTimeUsageMap().getOrDefault(machineToolId, new HashMap<>());

            Map<String, Integer> countMachineToolNoMap = machineToolParamVo.getCountMachineToolNoMap().getOrDefault(machineToolId, new HashMap<>());
            toolDemandPredictionVo.setMachineToolExistLife(sumToolLifeMap.getOrDefault(toolName, 0.0) - sumTimeUsageMap.getOrDefault(toolName, 0.0));
            toolDemandPredictionVo.setMachineToolExistNumber(countMachineToolNoMap.getOrDefault(toolName, 0));
            //计算备刀寿命值
            String key = toolDemandPredictionVo.getId() + toolDemandPredictionVo.getToolCode();
            Map<String, Double> backupRemainingLifeMap = backupToolLifeVo.getBackupRemainingLifeMap();
            Map<String, Double> backupToolLifeMap = backupToolLifeVo.getBackupToolLifeMap();
            Map<String, Integer> backupCountMap = backupToolLifeVo.getBackupCountMap();
            double backToolLife = backupToolLifeMap.getOrDefault(key, 0.0);
            double backRemainingLife = backupRemainingLifeMap.getOrDefault(key, 0.0);
            toolDemandPredictionVo.setBackupLife(backToolLife);
            toolDemandPredictionVo.setBackupTimeUsage(backRemainingLife);
            toolDemandPredictionVo.setBackupNumber(backupCountMap.getOrDefault(key, 0));


            Map<String, List<String>> backupLocationMap = backupToolLifeVo.getBackupLocationMap();
            toolDemandPredictionVo.setLocationName(backupLocationMap.getOrDefault(key, new ArrayList<>()));

            toolDemandPredictionVo.setLife(toolDefaultLifeMap.getOrDefault(key , 60.0));
            setStatusByCondition(toolDemandPredictionVo
                    , sumToolLifeMap.getOrDefault(toolName, 0.0)
                    , sumTimeUsageMap.getOrDefault(toolName, 0.0)
                    , backToolLife
                    , backRemainingLife
                    , sumMap);
        });
    }

    private void buildTaskStatus(List<ToolDemandPredictionVo> toolList, Map<String, Double> preToolUsageTimeMap) {
        //校验如果分配的工序任务全未管理子程序 则直接返回
        if (CollectionUtil.isEmpty(toolList)) {
            return;
        }
        //初始化snMap
        initSnFlagMap();
        initToolParamMap();

        //分组查询机床的刀具列表
        //Map<Integer , List<IncBoxParamVo>>  machineToolParamMap = queryToolParamBySnCode(toolList);
        MachineToolParamVo machineToolParamVo = queryToolParamBySnCode(toolList);

        BackupToolLifeVo backupToolLifeVo = queryBackupToolMapReload(toolList);

        //设置刀具清单状态(机床采集数据设置)
        Map<String, Integer> countMap = toolList
                .stream()
                .collect(Collectors.toMap(ToolDemandPredictionVo::getToolCode, value -> 1, Integer::sum));
        Map<String, List<ToolDemandPredictionVo>> groupByMap = toolList
                .stream()
                .collect(Collectors.groupingBy(ToolDemandPredictionVo::getToolCode));
        Map<String, Double> sumMap = groupByMap
                .entrySet()
                .stream()
                .collect(Collectors.toMap(Map.Entry::getKey, value -> value.getValue()
                        .stream()
                        .mapToDouble(toolDemandPredictionVo -> toolDemandPredictionVo.getSingleTime().doubleValue()).sum()));
        if (CollectionUtil.isNotEmpty(groupByMap)) {
            List<ToolDemandPredictionVo> sortList = new ArrayList<>();
            groupByMap.forEach((k, v) -> {
                sortList.addAll(v);
            });
            toolList = sortList;
        }
        toolList.forEach(toolDemandPredictionVo -> {
            toolDemandPredictionVo.setCount(countMap.get(toolDemandPredictionVo.getToolCode()));
            toolDemandPredictionVo.setCountTime(sumMap.get(toolDemandPredictionVo.getToolCode()));
            Map<Integer, List<IncBoxParamVo>> machineToolParamMap = machineToolParamVo.getMachineToolParamMap();

            Integer machineToolId = toolDemandPredictionVo.getMachineToolId();
            List<IncBoxParamVo> incBoxParamVos = machineToolParamMap.getOrDefault(machineToolId, new ArrayList<>());
            if (CollectionUtil.isNotEmpty(incBoxParamVos)) {
                String toolName = toolDemandPredictionVo.getToolCode().replaceFirst(".", "");
                Map<String, Double> sumToolLifeMap = machineToolParamVo.getMachineSumToolLifeMap().getOrDefault(machineToolId, new HashMap<>());

                Map<String, Double> sumTimeUsageMap = machineToolParamVo.getMachineSumTimeUsageMap().getOrDefault(machineToolId, new HashMap<>());

                Map<String, Integer> countMachineToolNoMap = machineToolParamVo.getCountMachineToolNoMap().getOrDefault(machineToolId, new HashMap<>());
                toolDemandPredictionVo.setMachineToolExistLife(sumToolLifeMap.getOrDefault(toolName, 0.0) - sumTimeUsageMap.getOrDefault(toolName, 0.0));
                toolDemandPredictionVo.setMachineToolExistNumber(countMachineToolNoMap.getOrDefault(toolName, 0));
                //计算备刀寿命值
                String key = toolDemandPredictionVo.getId() + toolDemandPredictionVo.getToolCode();
                Map<String, Double> backupRemainingLifeMap = backupToolLifeVo.getBackupRemainingLifeMap();
                Map<String, Double> backupToolLifeMap = backupToolLifeVo.getBackupToolLifeMap();
                double backToolLife = backupToolLifeMap.getOrDefault(key, 0.0);
                double backRemainingLife = backupRemainingLifeMap.getOrDefault(key, 0.0);
                toolDemandPredictionVo.setBackupLife(backToolLife);
                toolDemandPredictionVo.setBackupTimeUsage(backRemainingLife);


                Map<String, List<String>> backupLocationMap = backupToolLifeVo.getBackupLocationMap();
                toolDemandPredictionVo.setLocationName(backupLocationMap.getOrDefault(key, new ArrayList<>()));

                toolDemandPredictionVo.setLife(getDefaultLifeReload(toolDemandPredictionVo.getToolCode(), toolDemandPredictionVo.getToolModel()));
                setStatusByCondition(toolDemandPredictionVo
                        , sumToolLifeMap.getOrDefault(toolName, 0.0)
                        , sumTimeUsageMap.getOrDefault(toolName, 0.0)
                        , backToolLife
                        , backRemainingLife
                        , sumMap);
            }
        });
    }

    private BackupToolLifeVo queryBackupToolMapReload(List<ToolDemandPredictionVo> toolList) {
        BackupToolLifeVo backupToolLifeVo = new BackupToolLifeVo();
        Map<String, Double> backupToolLifeMap = new HashMap<>();
        Map<String, Double> backupRemainingLifeMap = new HashMap<>();
        Map<String, List<String>> backupLocationMap = new HashMap<>();
        Map<String, Integer> backupCountMap = new HashMap<>();

        Map<String, List<ToolDemandPredictionVo>> groupByGroupIdMap = new HashMap<>();
        Map<String, List<ToolPartEntity>> groupByGroupIdToolListMap = new HashMap<>();
        if (CollectionUtil.isNotEmpty(toolList)) {
            //设置分组字段
            toolList.forEach(toolDemandPredictionVo -> {
                if (ObjectUtil.isNotNull(toolDemandPredictionVo)) {
                    toolDemandPredictionVo.setGroupId(toolDemandPredictionVo.getId() + toolDemandPredictionVo.getToolCode());
                }
            });
            groupByGroupIdMap = toolList.stream().collect(Collectors.groupingBy(ToolDemandPredictionVo::getGroupId));
            List<String> groupIds = new ArrayList<>(groupByGroupIdMap.keySet());
            List<ToolPartEntity> toolPartEntities = warehouseRespository.selectByBackUpStatusReload(groupIds);
            if (CollectionUtil.isNotEmpty(toolPartEntities)) {
                //将查询的备刀刀具按照backupId+toolNo的groupId分组
                groupByGroupIdToolListMap = toolPartEntities
                        .stream()
                        .collect(Collectors.groupingBy(ToolPartEntity::getGroupId));
            }
        }
        //分组后查询
        if (CollectionUtil.isNotEmpty(groupByGroupIdMap)) {
            for (Map.Entry<String, List<ToolDemandPredictionVo>> groupIdToolDemandPredictionVosEntry : groupByGroupIdMap.entrySet()) {
                List<ToolDemandPredictionVo> toolDemandPredictionVos = groupIdToolDemandPredictionVosEntry.getValue();
                String groupId = groupIdToolDemandPredictionVosEntry.getKey();
                if (CollectionUtil.isNotEmpty(toolDemandPredictionVos)) {
                    //将groupId对应的刀具预测list去重
                    List<ToolDemandPredictionVo> distinctList = toolDemandPredictionVos
                            .stream()
                            .distinct()
                            .collect(Collectors.toList());
                    for (ToolDemandPredictionVo toolDemandPredictionVo : distinctList) {
                        //获取对应的备刀list
                        List<ToolPartEntity> mapToolPartEntities = groupByGroupIdToolListMap.getOrDefault(groupId, new ArrayList<>());
                        if (CollectionUtil.isNotEmpty(mapToolPartEntities)) {
                            String key = toolDemandPredictionVo.getId() + toolDemandPredictionVo.getToolCode();
                            List<Integer> locationIds = mapToolPartEntities.stream().map(ToolPartEntity::getInventoryLocationId).collect(Collectors.toList());
                            backupLocationMap.put(key, transferLocationName(locationIds));
                            double backToolLife = mapToolPartEntities
                                    .stream()
                                    .mapToDouble(toolPart -> Double.parseDouble(toolPart.getLife().substring(0, toolPart.getLife().length() - 1)))
                                    .sum();
                            backupToolLifeMap.put(key, backToolLife);
                            double backRemainingLife = mapToolPartEntities
                                    .stream()
                                    .mapToDouble(toolPart -> Double.parseDouble(toolPart.getRemainingLife().substring(0, toolPart.getRemainingLife().length() - 1)))
                                    .sum();
                            backupRemainingLifeMap.put(key, backRemainingLife);
                            backupCountMap.put(key, mapToolPartEntities.size());
                        }
                    }
                    backupToolLifeVo.setBackupToolLifeMap(backupToolLifeMap);
                    backupToolLifeVo.setBackupRemainingLifeMap(backupRemainingLifeMap);
                    backupToolLifeVo.setBackupLocationMap(backupLocationMap);
                    backupToolLifeVo.setBackupCountMap(backupCountMap);
                }
            }
        }
        return backupToolLifeVo;
    }


    private BackupToolLifeVo queryBackupToolMap(List<ToolDemandPredictionVo> toolList, Map<String, Double> preToolTimeUsageMap) {
        BackupToolLifeVo backupToolLifeVo = new BackupToolLifeVo();
        Map<String, Double> backupToolLifeMap = new HashMap<>();
        Map<String, Double> backupRemainingLifeMap = new HashMap<>();
        Map<String, List<String>> backupLocationMap = new HashMap<>();
        //去重
        List<ToolDemandPredictionVo> distinctList = toolList.stream().distinct().collect(Collectors.toList());
        if (CollectionUtil.isNotEmpty(distinctList)) {
            distinctList.forEach(toolDemandPredictionVo -> {
                List<ToolPartEntity> toolPartEntity = warehouseRespository.selectByBackUpStatus(toolDemandPredictionVo.getId(), toolDemandPredictionVo.getToolCode(), toolDemandPredictionVo.getSubProgramName());
                if (CollectionUtil.isNotEmpty(toolPartEntity)) {
                    String key = toolDemandPredictionVo.getId() + toolDemandPredictionVo.getToolCode();
                    List<Integer> locationIds = toolPartEntity.stream().map(ToolPartEntity::getInventoryLocationId).collect(Collectors.toList());
                    backupLocationMap.put(key, transferLocationName(locationIds));
                    double backToolLife = toolPartEntity
                            .stream()
                            .mapToDouble(toolPart -> Double.parseDouble(toolPart.getLife().substring(0, toolPart.getLife().length() - 1)))
                            .sum();
                    backupToolLifeMap.put(key, backToolLife);
                    double backRemainingLife = toolPartEntity
                            .stream()
                            .mapToDouble(toolPart -> Double.parseDouble(toolPart.getRemainingLife().substring(0, toolPart.getRemainingLife().length() - 1)))
                            .sum();
                    backupRemainingLifeMap.put(key, backRemainingLife);
                }
            });
            backupToolLifeVo.setBackupToolLifeMap(backupToolLifeMap);
            backupToolLifeVo.setBackupRemainingLifeMap(backupRemainingLifeMap);
            backupToolLifeVo.setBackupLocationMap(backupLocationMap);
        }
        return backupToolLifeVo;
    }

    private MachineToolParamVo queryToolParamBySnCode(List<ToolDemandPredictionVo> toolList) {
        //toolList按照机床id分组
        Map<Integer, List<ToolDemandPredictionVo>> groupByMachineToolId = toolList.stream().collect(Collectors.groupingBy(ToolDemandPredictionVo::getMachineToolId));
        //机床采集刀具分组map
        Map<Integer, List<IncBoxParamVo>> machineToolParamMap = new HashMap<>();

        Map<Integer, Map<String, Double>> machineSumToolLifeMap = new HashMap<>();

        Map<Integer, Map<String, Double>> machineSumTimeUsageMap = new HashMap<>();

        Map<Integer, Map<String, Integer>> macCountMachineToolNoMap = new HashMap<>();

        MachineToolParamVo machineToolParamVo = new MachineToolParamVo();

        if (CollectionUtil.isNotEmpty(groupByMachineToolId)) {
            List<WarehouseEntity> warehouseEnties = warehouseRespository.getByIdReload(new ArrayList<>(groupByMachineToolId.keySet()));
            Map<Integer, String> groupByNameMap = new HashMap<>();
            Map<Integer, String> groupBySnCodeMap = new HashMap<>();
            if (CollectionUtil.isNotEmpty(warehouseEnties)) {
                warehouseEnties.forEach(warehouseEntity -> {
                    groupByNameMap.put(warehouseEntity.getId(), warehouseEntity.getName());
                    groupBySnCodeMap.put(warehouseEntity.getId(), warehouseEntity.getSnCode());
                });
            }
            for (Map.Entry<Integer, List<ToolDemandPredictionVo>> integerListEntry : groupByMachineToolId.entrySet()) {
                Integer k = integerListEntry.getKey();
                String machineToolName = groupByNameMap.getOrDefault(k, "");
                String snCode = groupBySnCodeMap.getOrDefault(k, "");
                if (!snFlagMap.get(machineToolName)
                        && CollectionUtil.isEmpty(toolParamsMap.get(machineToolName))) {
                    //初始值变化，采集异常 直接进行下一次循环
                    //System.out.println("1:"+System.currentTimeMillis());
                    try {
                        //DeviceClient deviceClient = ConnectDevice(snCode);
                        DeviceClient deviceClient =
                                new DeviceClient(snCode, "tcp://192.168.32.107:1883", null, null, null);
                        deviceClient.connect();
                        String id = deviceClient.getIdOf("/NC_LINK_ROOT/MACHINE/CONTROLLER/TOOL_PARAM");

                        int i = getLengthByGroup(k, deviceClient, id);
                        List<Object> length = deviceClient.easyQuery(3000, new QueryRequestItem.Builder().id(id).operation(Operation.GET_LENGTH).build());
                        //先Operation.GET_LENGTH取长度
                        List<Object> result = result = deviceClient.easyQuery(3000, new QueryRequestItem.Builder()
                                .id(id).addIndexRange(0, i - 1).build());
                        List<IncBoxParamVo> incBoxParamVos = CommonUtil.parseToolParams(result.get(0).toString());
                        toolParamsMap.put(machineToolName, incBoxParamVos);
                        machineToolParamMap.put(k, incBoxParamVos);
                        List<IncBoxParamVoChild> incBoxParamVoChildren = new ArrayList<>();
                        incBoxParamVos.forEach(incBoxParamVo -> {
                            IncBoxParamVoChild incBoxParamVoChild = new IncBoxParamVoChild();
                            //表示有刀 之后根据该刀寿命计算预测数量
                            //刀具额定寿命参数
                            Integer toolLife = Integer.valueOf(incBoxParamVo.getMax_time_usage());
                            double toolLifeDouble = 0.0;
                            if (toolLife == 0) {
                                toolLifeDouble = getDefaultLife("T" + incBoxParamVo.getName());
                            }
                            toolLifeDouble = toolLife.doubleValue();
                            //刀具使用寿命参数（该机床）
                            Double toolUsageTime = Double.valueOf(incBoxParamVo.getTime_usage());
                            //保留两位小数点并四舍五入
                            String format = new DecimalFormat("######0.00").format(toolUsageTime);
                            Double toolUsageTimeSub = Double.valueOf(format);
                            incBoxParamVoChild.setToolLifeDouble(toolLifeDouble);
                            incBoxParamVoChild.setToolUsageTime(toolUsageTimeSub);
                            BeanUtils.copyProperties(incBoxParamVo, incBoxParamVoChild);
                            incBoxParamVoChildren.add(incBoxParamVoChild);
                        });
                        //String toolName = toolDemandPredictionVo.getToolCode().replaceFirst(".", "");
                        //分组计算机床刀具寿命

                        Map<String, Integer> countMachineToolNoMap = incBoxParamVoChildren.stream().collect(Collectors.toMap(IncBoxParamVoChild::getName, value -> 1, Integer::sum));
                        macCountMachineToolNoMap.put(k, countMachineToolNoMap);

                        Map<String, List<IncBoxParamVoChild>> groupByMachineToolNoMap = incBoxParamVoChildren.stream().collect(Collectors.groupingBy(IncBoxParamVo::getName));
                        Map<String, Double> sumToolLifeMap = groupByMachineToolNoMap
                                .entrySet()
                                .stream()
                                .collect(Collectors.toMap(Map.Entry::getKey, value -> value.getValue()
                                        .stream()
                                        .mapToDouble(IncBoxParamVoChild::getToolLifeDouble).sum()));

                        machineSumToolLifeMap.put(k, sumToolLifeMap);

                        Map<String, Double> sumTimeUsageMap = groupByMachineToolNoMap
                                .entrySet()
                                .stream()
                                .collect(Collectors.toMap(Map.Entry::getKey, value -> value.getValue()
                                        .stream()
                                        .mapToDouble(IncBoxParamVoChild::getToolUsageTime).sum()));

                        machineSumTimeUsageMap.put(k, sumTimeUsageMap);

                    } catch (Exception e) {
                        //更新内存map 采集异常
                        snFlagMap.put(machineToolName, true);
                        machineToolParamMap.put(k, new ArrayList<>());
                        machineSumToolLifeMap.put(k, new HashMap<>());
                        machineSumToolLifeMap.put(k, new HashMap<>());
                        macCountMachineToolNoMap.put(k, new HashMap<>());
                        log.error(e.getMessage());
                    }
                }
            }
            machineToolParamVo.setMachineToolParamMap(machineToolParamMap);
            machineToolParamVo.setMachineSumToolLifeMap(machineSumToolLifeMap);
            machineToolParamVo.setMachineSumTimeUsageMap(machineSumTimeUsageMap);
            machineToolParamVo.setCountMachineToolNoMap(macCountMachineToolNoMap);
        }
        return machineToolParamVo;
    }


    private List<String> transferLocationName(List<Integer> locationIds) {
        return inventoryLocationRespository.transferLocationName(locationIds);
    }

    public Double getDefaultLife(String toolCode) {
        QueryWrapper<ToolLifeEntity> wrapper = new QueryWrapper<>();
        wrapper.eq("classify", toolCode);
        wrapper.eq("type_flag", 1);
        ToolLifeEntity toolLifeEntity = toolLifeMapper.selectOne(wrapper);
        if (ObjectUtil.isNotNull(toolLifeEntity) && ObjectUtil.isNotNull(toolLifeEntity.getLife())) {
            return toolLifeEntity.getLife().doubleValue();
        }
        return 60.0;
    }

    public Double getDefaultLifeReload(String toolCode, String toolIdnr) {
        QueryWrapper<ToolLifeEntity> wrapper = new QueryWrapper<>();
        wrapper.eq("classify", toolCode);
        wrapper.eq("type_flag", 1);
        ToolLifeEntity toolLifeEntity = toolLifeMapper.selectOne(wrapper);
        if (ObjectUtil.isNotNull(toolLifeEntity) && ObjectUtil.isNotNull(toolLifeEntity.getLife())) {
            return toolLifeEntity.getLife().doubleValue();
        }
        //根据零件配置的寿命来进行计算
        QueryWrapper<ToolForkInfoEntity> toolForkWrapper = new QueryWrapper<>();
        toolForkWrapper.eq("idnr", toolIdnr);
        List<ToolForkInfoEntity> toolForkInfoEntities = toolForkInfoMapper.selectList(toolForkWrapper);

        if (CollectionUtil.isNotEmpty(toolForkInfoEntities)) {
            List<Double> timeList = new ArrayList<>();
            toolForkInfoEntities.forEach(toolForkInfoEntity -> {
                QueryWrapper<ToolLifeEntity> wrapper1 = new QueryWrapper<>();
                wrapper1.eq("classify", toolForkInfoEntity.getPartno());
                wrapper1.eq("type_flag", 0);
                ToolLifeEntity toolLifeEntity1 = toolLifeMapper.selectOne(wrapper1);
                if (ObjectUtil.isNotNull(toolLifeEntity1) && ObjectUtil.isNotNull(toolLifeEntity1.getLife())) {
                    timeList.add(toolLifeEntity1.getLife().doubleValue());
                }
            });
            if (CollectionUtil.isNotEmpty(timeList)) {
                return CollectionUtil.min(timeList);
            }
        }
        return 60.0;
    }

    /**
     * 获取总成配置寿命
     * @param groupByToolCodeMap
     * @param toolCode
     * @return
     */
    public Double getDefaultLifeGroup(Map<String, List<ToolLifeEntity>> groupByToolCodeMap, String toolCode) {
        List<ToolLifeEntity> mapToolCodeList = groupByToolCodeMap.getOrDefault(toolCode, new ArrayList<>());
        if (CollectionUtil.isNotEmpty(mapToolCodeList) && ObjectUtil.isNotNull(mapToolCodeList.get(0).getLife())) {
            //返回总成配置寿命
            return mapToolCodeList.get(0).getLife().doubleValue();
        }
        return 60.0;
    }

    /**
     * 获取零件对应最小配置寿命
     * @param groupByToolModelMap
     * @param toolModel
     * @return
     */
    public Double getDefaultPartLifeGroup(Map<String, List<ToolLifeEntity>> groupByToolModelMap, String toolModel) {
        List<ToolLifeEntity> mapToolModelList = groupByToolModelMap.getOrDefault(toolModel, new ArrayList<>());
        if (CollectionUtil.isNotEmpty(mapToolModelList) && ObjectUtil.isNotNull(mapToolModelList.get(0).getLife())) {
            //获取零件对应最小配置寿命
            return CollectionUtil.min(mapToolModelList
                    .stream()
                    .map(ToolLifeEntity::getLife)
                    .collect(Collectors.toList())).doubleValue();
        }
        return 60.0;
    }


    public ToolForkCountVo getDefaultLifeReload(String toolType, List<String> partnos) {
        //将toolType转换为partno
        if (CollectionUtil.isNotEmpty(partnos)) {
            List<ToolForkCountVo> timeList = new ArrayList<>();
            for (String partno : partnos) {
                QueryWrapper<ToolLifeEntity> wrapper = new QueryWrapper<>();
                wrapper.eq("classify", partno);
                wrapper.eq("type_flag", 0);
                ToolLifeEntity toolLifeEntity = toolLifeMapper.selectOne(wrapper);
                if (ObjectUtil.isNotNull(toolLifeEntity) && ObjectUtil.isNotNull(toolLifeEntity.getLife())) {
                    ToolForkCountVo toolForkCountVo = new ToolForkCountVo();
                    toolForkCountVo.setPartno(partno);
                    toolForkCountVo.setLife(toolLifeEntity.getLife().doubleValue());
                    timeList.add(toolForkCountVo);
                }
            }
            if (CollectionUtil.isNotEmpty(timeList)) {
                List<ToolForkCountVo> result = timeList
                        .stream()
                        .sorted(Comparator.comparing(ToolForkCountVo::getLife))
                        .collect(Collectors.toList());
                if (CollectionUtil.isNotEmpty(result)) {
                    return result.get(0);
                }
            }
            ToolForkCountVo toolForkCountVo = new ToolForkCountVo();
            toolForkCountVo.setLife(60.0);
            return toolForkCountVo;
        }
        ToolForkCountVo toolForkCountVo = new ToolForkCountVo();
        toolForkCountVo.setLife(60.0);
        return toolForkCountVo;
    }

    private void initToolParamMap() {
        toolParamsMap.put("B1", new ArrayList<>());
        toolParamsMap.put("B2", new ArrayList<>());
        toolParamsMap.put("B3", new ArrayList<>());
        toolParamsMap.put("B4", new ArrayList<>());
        toolParamsMap.put("B5", new ArrayList<>());
        toolParamsMap.put("B6", new ArrayList<>());
        toolParamsMap.put("B7", new ArrayList<>());
        toolParamsMap.put("B8", new ArrayList<>());
        toolParamsMap.put("B9", new ArrayList<>());
        toolParamsMap.put("B10", new ArrayList<>());
        toolParamsMap.put("B11", new ArrayList<>());
        toolParamsMap.put("B12", new ArrayList<>());
        toolParamsMap.put("B13", new ArrayList<>());
        toolParamsMap.put("B14", new ArrayList<>());
        toolParamsMap.put("B15", new ArrayList<>());
        toolParamsMap.put("B16", new ArrayList<>());
        toolParamsMap.put("B17", new ArrayList<>());
    }

    private String transferToolNoList(IncBoxParamVo incBoxParamVo) {
        return "T" + incBoxParamVo.getName();
    }

    private int countNumber(Double maxTimeUsage, Double timeUsage, BigDecimal singleTime) {
        Double singleTimeDouble = singleTime.doubleValue();
        //获取刀具剩余时长
        Double remainingLife = maxTimeUsage - timeUsage;
        if (remainingLife >= singleTimeDouble) {
            return 0;
        } else {
            Double requireTime = singleTimeDouble - remainingLife;
            //刀具剩余寿命消耗完后，计算所需寿命
            return (int) Math.ceil(requireTime / maxTimeUsage);
        }
    }

//    private int countNumberReport(Double maxTimeUsage, Double timeUsage, BigDecimal singleTime) {
//        Double singleTimeDouble = singleTime.doubleValue();
//        //获取刀具剩余时长
//        Double remainingLife = maxTimeUsage;
//        if (remainingLife >= singleTimeDouble) {
//            return 0;
//        } else {
//            Double requireTime = singleTimeDouble - remainingLife;
//            //刀具剩余寿命消耗完后，计算所需寿命
//            return (int) Math.ceil(requireTime / maxTimeUsage);
//        }
//    }

    private int countNumberReport(Double maxTimeUsage, Double timeUsage, BigDecimal singleTime) {
        Double singleTimeDouble = singleTime.doubleValue();
        //获取刀具剩余时长
        Double remainingLife = maxTimeUsage;
        if (remainingLife >= singleTimeDouble) {
            return 0;
        } else {
            //Double requireTime = singleTimeDouble - remainingLife;
            //刀具剩余寿命消耗完后，计算所需寿命
            return (int) Math.ceil(singleTimeDouble / maxTimeUsage);
        }
    }

    private void initSnFlagMap() {
        snFlagMap.put("B1", false);
        snFlagMap.put("B2", false);
        snFlagMap.put("B3", false);
        snFlagMap.put("B4", false);
        snFlagMap.put("B5", false);
        snFlagMap.put("B6", false);
        snFlagMap.put("B7", false);
        snFlagMap.put("B8", false);
        snFlagMap.put("B9", false);
        snFlagMap.put("B10", false);
        snFlagMap.put("B11", false);
        snFlagMap.put("B12", false);
        snFlagMap.put("B13", false);
        snFlagMap.put("B14", false);
        snFlagMap.put("B15", false);
        snFlagMap.put("B16", false);
        snFlagMap.put("B17", false);
    }

    public DeviceClient ConnectDevice(String sn) throws InvalidException, MqttException {
        DeviceClient ret = clientMap.get(sn);
        if (ret != null) {
            if (!ret.isConnected())
                if (!ret.connect()) {
                    ret = null;
                }

        }
        if (ret == null) {
            DeviceClient deviceClient = new DeviceClient(sn, "tcp://192.168.32.107:1883", null, null, null);
            if (deviceClient != null || !deviceClient.isConnected()) {
                deviceClient.connect();
            }
            ret = deviceClient;
            clientMap.put(sn, deviceClient);
        }
        return ret;
    }


    public Object getDirectRetrievalList(QryDirectRetrievalReq qryDirectRetrievalReq) {
        PageHelper.startPage(qryDirectRetrievalReq.getPageNum(), qryDirectRetrievalReq.getPageSize());
        List<DirectRetrievalVo> directRetrievalVos = new ArrayList<>();
        if (StringUtils.isNotEmpty(qryDirectRetrievalReq.getToolNo())) {
            directRetrievalVos = toolForkInfoRespository.getDirectRetrievalListByToolNo(qryDirectRetrievalReq);
        } else {
            directRetrievalVos = toolForkInfoRespository.getDirectRetrievalList(qryDirectRetrievalReq);
        }
        PageInfo<DirectRetrievalVo> pageInfo = new PageInfo<>(directRetrievalVos);
        //拼接图片前缀以及设置总库存
        pageInfo.getList().forEach(directRetrievalVo -> {
            directRetrievalVo.setImage(minioProp.getBaseUrl() + minioProp.getBucketName() + "/" + directRetrievalVo.getImage());
            if (StringUtils.isNotEmpty(directRetrievalVo.getPartno())) {
                directRetrievalVo.setTotalLocationNum(inventoryLocationRespository.getTotalInventoryByPartno(directRetrievalVo.getPartno()));
            }
        });
        Map<String, Object> retMap = new HashMap<>();
        retMap.put("list", pageInfo.getList());
        retMap.put("total", pageInfo.getTotal());
        return retMap;
    }

    public Object getEmployeeRetrievalIndex(EmployeeRetrievalIndexReq employeeRetrievalIndexReq) {
        //List<String> employeeNames = processManageService.checkAllotEmployeeGroup(null , null);
        PageHelper.startPage(employeeRetrievalIndexReq.getPageNum(), employeeRetrievalIndexReq.getPageSize());
        List<AllotEmployeeEntity> allotEmployees = allotEmployeeRepository.queryAllotEmployee(employeeRetrievalIndexReq.getEmployeeName());
        PageInfo<AllotEmployeeEntity> pageInfo = new PageInfo<>(allotEmployees);
        return new PageResult<>(pageInfo.getList(), pageInfo.getTotal());
    }

    public Object getEmployeeTaskList(EmployeeTasksReq employeeTasksReq) {
        PageHelper.startPage(employeeTasksReq.getPageNum(), employeeTasksReq.getPageSize());
        QueryWrapper<MachineToolTaskEntity> wrapper = new QueryWrapper<>();
        wrapper.eq("machine_tool_name", employeeTasksReq.getMachineToolName());
        if (ObjectUtil.isNotNull(employeeTasksReq.getStartTime())) {
            wrapper.ge("start_time", employeeTasksReq.getStartTime()).le("start_time", employeeTasksReq.getEndTime());
        }
        List<MachineToolTaskEntity> machineToolTaskEntities = machineToolTaskRespository.selectEmployeeTaskList(employeeTasksReq);
        //List<MachineToolTaskEntity> machineToolTaskEntities = machineToolTaskMapper.selectList(wrapper);
        PageInfo<MachineToolTaskEntity> pageInfo = new PageInfo<>(machineToolTaskEntities);
        return new PageResult<>(pageInfo.getList(), pageInfo.getTotal());
    }

    private PageResult<EmployeeRetrievalVo> buildEmployeeRetrievalVos(Map<String, List<EmployeeRetrievalBuildVo>> employeeGroup, EmployeeRetrievalIndexReq employeeRetrievalIndexReq) {
        List<EmployeeRetrievalVo> retList = new ArrayList<>();
        List<EmployeeRetrievalVo> pageList = new ArrayList<>();
        employeeGroup.forEach((key, value) -> {
            //设置人员基础信息
            QueryWrapper<EmployeeEntity> wrapper = new QueryWrapper<>();
            wrapper.eq("employee_no", key);
            EmployeeEntity employeeEntity = employeeMapper.selectOne(wrapper);
            EmployeeRetrievalVo employeeRetrievalVo = new EmployeeRetrievalVo();
            employeeRetrievalVo.setEmployeeName(employeeEntity.getEmployeeName());
            employeeRetrievalVo.setId(employeeEntity.getId());
            employeeRetrievalVo.setEmployeeNo(employeeEntity.getEmployeeNo());
            if (CollectionUtil.isNotEmpty(value)) {
                setArgs(value, employeeRetrievalVo);
            }
            retList.add(employeeRetrievalVo);
        });
        if (CollectionUtil.isNotEmpty(retList)) {
            pageList = CommonUtil.pageList(retList, employeeRetrievalIndexReq.getPageNum(), employeeRetrievalIndexReq.getPageSize());
        }
        return new PageResult<>(pageList, (long) retList.size());
    }

    private void setArgs(List<EmployeeRetrievalBuildVo> value, EmployeeRetrievalVo employeeRetrievalVo) {
        //设置工单号
        List<String> taskIdList = value.stream()
                .map(EmployeeRetrievalBuildVo::getTaskId)
                .filter(ObjectUtil::isNotNull)
                .distinct()
                .collect(Collectors.toList());
        employeeRetrievalVo.setTaskIds(CommonUtil.appendString(taskIdList));
        //设置机床名
        List<String> machineToolNameList = value.stream()
                .map(EmployeeRetrievalBuildVo::getMachineToolName)
                .filter(ObjectUtil::isNotNull)
                .distinct()
                .collect(Collectors.toList());
        employeeRetrievalVo.setMachineToolName(CommonUtil.appendString(machineToolNameList));
        //设置程序名
        List<String> programList = value.stream()
                .filter(employeeRetrievalBuildVo -> ObjectUtil.isNotNull(employeeRetrievalBuildVo.getProgramParam()))
                .map(employeeRetrievalBuildVo -> {
                    ProgramParamVo programParamVo = JSONObject.parseObject(employeeRetrievalBuildVo.getProgramParam(), ProgramParamVo.class);
                    return programParamVo.getProgramNum();
                })
                .distinct()
                .filter(ObjectUtil::isNotNull)
                .filter(StringUtils::isNotEmpty)
                .collect(Collectors.toList());
        employeeRetrievalVo.setProgramNums(CommonUtil.appendString(programList));
    }

    public List<Integer> getOrderIdsByTaskIds(String taskIds) throws ToolManageException {
        if (StringUtils.isEmpty(taskIds)) {
            throw new ToolManageException(ToolManageEx.ORDER_NO_EXIST.getCode(), ToolManageEx.ORDER_NO_EXIST.getMsg());
        }
        //返回对应orderId
        return Arrays.stream(taskIds.split(","))
                .map(s -> orderRespository.getIdByTaskId(s))//将taskId转化为orderId
                .collect(Collectors.toList());
    }

    public Object getEmployeeRetrievalDetail(Integer id, Integer pageNum, Integer pageSize) {
        PageHelper.startPage(pageNum, pageSize);
        PageInfo<EmployeeRetrievalDetailVo> pageInfo = new PageInfo<>(machineToolTaskRespository.selectTaskByEmployeeId(id));
        return new PageResult<>(pageInfo.getList(), pageInfo.getTotal());
    }

    /**
     * 人员取料刀具需求预测
     *
     * @param empToolDemandPredictionReq
     * @return
     * @throws ToolScheduleException
     */
    public List<ToolDemandPredictionVo> getEmpToolDemandPredictionListReload(EmpToolDemandPredictionReq empToolDemandPredictionReq) throws ToolScheduleException {
        if (ObjectUtil.isNull(empToolDemandPredictionReq.getStartTime())) {
            empToolDemandPredictionReq.setStartTime(new Date());
            empToolDemandPredictionReq.setEndTime(CommonUtil.addTime48h());
        }
        Map<String, Object> retMap = new HashMap<>();
        //List<Integer> idList = employeeRepository.selectTaskIdsByEmployeeIds(empToolDemandPredictionReq);
        List<Integer> idList = empToolDemandPredictionReq.getIds();
        getToolListReload(empToolDemandPredictionReq.getPageNum(), empToolDemandPredictionReq.getPageSize(), idList, retMap, empToolDemandPredictionReq.getTaskIds(), empToolDemandPredictionReq.getSeqs(), empToolDemandPredictionReq.getMachineToolIds());
        return (List<ToolDemandPredictionVo>) retMap.get("toolList");
    }

    /**
     * 人员取料刀具需求预测
     *
     * @param empToolDemandPredictionReq
     * @return
     * @throws ToolScheduleException
     */
    public Object getEmpToolDemandPredictionList(EmpToolDemandPredictionReq empToolDemandPredictionReq) throws ToolScheduleException {
        if (ObjectUtil.isNull(empToolDemandPredictionReq.getStartTime())) {
            empToolDemandPredictionReq.setStartTime(new Date());
            empToolDemandPredictionReq.setEndTime(CommonUtil.addTime48h());
        }
        Map<String, Object> retMap = new HashMap<>();
        //List<Integer> idList = employeeRepository.selectTaskIdsByEmployeeIds(empToolDemandPredictionReq);
        List<Integer> idList = empToolDemandPredictionReq.getIds();
        getToolListReload(empToolDemandPredictionReq.getPageNum(), empToolDemandPredictionReq.getPageSize(), idList, retMap, empToolDemandPredictionReq.getTaskIds(), empToolDemandPredictionReq.getSeqs(), empToolDemandPredictionReq.getMachineToolIds());
        return retMap;
    }

    public Object getEmpToolDemandPredictionChild(Integer employeeId) {
        QueryWrapper<EmployeeEntity> wrapper = new QueryWrapper<>();
        wrapper.eq("id", employeeId);
        return employeeMapper.selectOne(wrapper);
    }

    public Object getMacToolDemandPredictionList(MacToolDemandPredictionReq macToolDemandPredictionReq) throws ToolScheduleException {
        if (ObjectUtil.isNull(macToolDemandPredictionReq.getStartTime())) {
            macToolDemandPredictionReq.setStartTime(new Date());
            macToolDemandPredictionReq.setEndTime(CommonUtil.addTime48h());
        }
        Map<String, Object> retMap = new HashMap<>();
        //TO DO 机床需求预测加入机床id过滤
        List<Integer> idList = machineToolTaskRespository.selectTaskByMachineToolIds(macToolDemandPredictionReq.getIds(), macToolDemandPredictionReq.getStartTime(), macToolDemandPredictionReq.getEndTime());
        getToolList(macToolDemandPredictionReq.getPageNum(), macToolDemandPredictionReq.getPageSize(), idList, retMap, macToolDemandPredictionReq.getTaskId(), macToolDemandPredictionReq.getSeqs(), new ArrayList<>());
        return retMap;
    }

    public Object getTaskRetrievalDetail(TaskDemandPredictionReq taskDemandPredictionReq) {
        Map<String, Object> retMap = new HashMap<>();
        getToolList(taskDemandPredictionReq.getPageNum(), taskDemandPredictionReq.getPageSize(), taskDemandPredictionReq.getMachineToolTaskIds(), retMap, taskDemandPredictionReq.getTaskIds(), taskDemandPredictionReq.getSeqs(), taskDemandPredictionReq.getMachineToolIds());
        return retMap;
    }

    public Object getWarehouseInventoryByToolNo(String toolNo) {
        return assemblyToolInventoryRepository.getWarehouseInventoryByToolNo(toolNo);
    }

    public Object getLocationInventory(String type) {
        Map<String, Object> retMap = inventoryLocationRespository.getLocationInventory(type);
        return null;
    }

    @Transactional
    public ResponseBody empOutboundAssemblyTool(EmpOutboundAssemblyToolReq empOutboundAssemblyToolReq) {
        if (CollectionUtil.isNotEmpty(empOutboundAssemblyToolReq.getOutBoundAssemblyReqs())) {
            List<ToolPartEntity> uniqueIds = new ArrayList<>();
            empOutboundAssemblyToolReq.getOutBoundAssemblyReqs().forEach(outBoundAssemblyReq -> {
                try {
                    uniqueIds.addAll(inventoryLocationService.outboundLocationAssemblyTool(outBoundAssemblyReq));
                } catch (ToolLifeCycleException e) {
                    log.error(e.getCode(), e.getMsg());
                }
            });
            return ResponseBody.success(uniqueIds);
        }
        return ResponseBody.error("100001", "取料异常");
    }

    @Transactional
    public List<ToolPartEntity> empOutboundAssemblyToolList(EmpOutboundAssemblyToolReq empOutboundAssemblyToolReq) {
        List<ToolPartEntity> outboundList = new ArrayList<>();
        empOutboundAssemblyToolReq.getOutBoundAssemblyReqs().forEach(outBoundAssemblyReq -> {
            Integer id = toolInventoryLocationRespository.selectOutboundRecord(outBoundAssemblyReq);
            List<ToolPartEntity> toolPartEntities = toolInventoryLocationRespository.selectOutboundList(id);
            outboundList.addAll(toolPartEntities);
        });
        return outboundList;
    }

    @Transactional
    public ResponseBody empInboundAssemblyTool(EmpInboundAssemblyToolReq empInboundAssemblyToolReq) {
        if (CollectionUtil.isNotEmpty(empInboundAssemblyToolReq.getInboundAssemblyReqs())) {
            empInboundAssemblyToolReq.getInboundAssemblyReqs().forEach(inBoundAssemblyReq -> {
                try {
                    inventoryLocationService.inboundUniqueAssemblyTool(inBoundAssemblyReq);
                } catch (ToolLifeCycleException e) {
                    System.out.println("e = " + e);
                    log.error(e.getCode(), e.getMsg());
                }
            });
            return ResponseBody.success();
        }
        return ResponseBody.error("100001", "入库异常");
    }

    public Object getDirectRetrievalStock(String partno) {

        return null;
    }

    @Transactional
    public Object directRetrieval(DirectRetrievalReq directRetrievalReq) throws ToolLifeCycleException, ToolManageException {
        InBoundOrOutBoundReq inBoundOrOutBoundReq = new InBoundOrOutBoundReq();
        List<OrderEntity> orderEntities = orderMapper.selectList(new QueryWrapper<>());
        List<String> collect = orderEntities.stream().map(orderEntity -> orderEntity.getMaterialNo().trim()).filter(s -> ObjectUtil.isNotNull(s) && StringUtil.isNotEmpty(s)).collect(Collectors.toList());
        if (!collect.contains(directRetrievalReq.getProductionNum())) {
            throw new ToolManageException(ToolManageEx.ORDER_NO_EXIST.getCode(), ToolManageEx.ORDER_NO_EXIST.getMsg());
        }
        BeanUtils.copyProperties(directRetrievalReq, inBoundOrOutBoundReq);
        //出库的零件集合
        List<ToolPartEntity> outboundList = inventoryLocationService.outboundLocationTool(inBoundOrOutBoundReq);
        //入库到对应库位
        InboundToolReq inboundToolReq = new InboundToolReq();
        inboundToolReq.setInboundTools(outboundList);
        inboundToolReq.setLocationId(directRetrievalReq.getInboundLocationId());
        inboundToolReq.setBz(directRetrievalReq.getBz());
        inboundToolReq.setNumber(directRetrievalReq.getNumber());
        inboundToolReq.setOperator(directRetrievalReq.getOperator());
        inventoryLocationService.inboundUniqueTool(inboundToolReq);
        return Boolean.TRUE;
    }

    public Object getEmployeeTaskDetail(GetEmployeeTaskDetailReq getEmployeeTaskDetailReq) {
        PageHelper.startPage(getEmployeeTaskDetailReq.getPageNum(), getEmployeeTaskDetailReq.getPageSize());
        PageInfo<EmployeeRetrievalDetailVo> pageInfo = new PageInfo<>(machineToolTaskRespository.selectEmployeeTask(getEmployeeTaskDetailReq));
        return new PageResult<>(pageInfo.getList(), pageInfo.getTotal());
    }

    /**
     * 实时预测刀具清单
     *
     * @param unmetToolReq
     * @return
     */
    public Object getUnmetToolList(UnmetToolReq unmetToolReq) {
        Map<String, Object> retMap = new HashMap<>();
        //筛选任务id
        List<String> taskIds = machineToolTaskRespository.selectTaskIds(unmetToolReq);
        if (CollectionUtil.isEmpty(taskIds)) {
            retMap.put("toolList", new ArrayList<>());
            retMap.put("total", 0);
            return retMap;
        }
        List<MachineToolTaskEntity> machineToolTaskEntities = machineToolTaskRespository.selectIdsByConditionReload(taskIds, unmetToolReq.getMachineToolId(), unmetToolReq.getCreateLeftTime(), unmetToolReq.getCreateEndTime());
        //根据员工id过滤
        if (ObjectUtil.isNotNull(unmetToolReq.getEmployeeId())) {
            QueryWrapper<EmployeeMachineToolConnectEntity> wrapper = new QueryWrapper<>();
            wrapper.eq("employee_id", unmetToolReq.getEmployeeId());
            List<EmployeeMachineToolConnectEntity> employeeMachineToolConnectEntities = employeeMachineToolConnectMapper.selectList(wrapper);
            if (CollectionUtil.isNotEmpty(employeeMachineToolConnectEntities)) {
                List<Integer> empFilterList = employeeMachineToolConnectEntities.stream().map(EmployeeMachineToolConnectEntity::getMachineToolTaskId).collect(Collectors.toList());
                if (CollectionUtil.isNotEmpty(empFilterList)) {
                    machineToolTaskEntities = machineToolTaskEntities.stream().filter(machineToolTaskEntity -> empFilterList.contains(machineToolTaskEntity.getId())).collect(Collectors.toList());
                }
            } else {
                machineToolTaskEntities = new ArrayList<>();
            }
        }
        List<Integer> ids = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(machineToolTaskEntities)) {
            if (!unmetToolReq.getFlag1()) {
                //过滤掉已开始的任务
                machineToolTaskEntities = machineToolTaskEntities.stream().filter(machineToolTaskEntity -> ObjectUtil.isNull(machineToolTaskEntity.getActualStartTime())).collect(Collectors.toList());
            }
            ids = machineToolTaskEntities.stream().map(MachineToolTaskEntity::getId).collect(Collectors.toList());
        }
        getUnmetTool(unmetToolReq.getPageNum(), unmetToolReq.getPageSize(), ids, retMap, unmetToolReq.getFlag(), unmetToolReq.getTaskIds(), unmetToolReq.getSeqs(), unmetToolReq.getFlag2());
        return retMap;
    }

    /**
     * 预测具体任务清单
     *
     * @return
     */
    public Object getTaskUnmetToolList(List<Integer> id, Integer pageNum, Integer pageSize, boolean flag, boolean flag2) {
        Map<String, Object> retMap = new HashMap<>();
        return retMap;
    }


    public List<ToolDemandPredictionVo> getUnmetToolListReload(UnmetToolReqReload unmetToolReloadReq) {
        Map<String, Object> retMap = new HashMap<>();
        //筛选任务id
        List<String> taskIds = orderRespository.selectByConditionReload(unmetToolReloadReq);
        if (CollectionUtil.isEmpty(taskIds)) {
            retMap.put("toolList", new ArrayList<>());
            retMap.put("total", 0);
            return new ArrayList<>();
        }
        List<MachineToolTaskEntity> machineToolTaskEntities = machineToolTaskRespository.selectIdsByConditionReload(taskIds, unmetToolReloadReq.getMachineToolId(), unmetToolReloadReq.getCreateLeftTime(), unmetToolReloadReq.getCreateEndTime());
        //根据员工id过滤
        if (ObjectUtil.isNotNull(unmetToolReloadReq.getEmployeeId())) {
            QueryWrapper<EmployeeMachineToolConnectEntity> wrapper = new QueryWrapper<>();
            wrapper.eq("employee_id", unmetToolReloadReq.getEmployeeId());
            List<EmployeeMachineToolConnectEntity> employeeMachineToolConnectEntities = employeeMachineToolConnectMapper.selectList(wrapper);
            if (CollectionUtil.isNotEmpty(employeeMachineToolConnectEntities)) {
                List<Integer> empFilterList = employeeMachineToolConnectEntities.stream().map(EmployeeMachineToolConnectEntity::getMachineToolTaskId).collect(Collectors.toList());
                if (CollectionUtil.isNotEmpty(empFilterList)) {
                    machineToolTaskEntities = machineToolTaskEntities.stream().filter(machineToolTaskEntity -> empFilterList.contains(machineToolTaskEntity.getId())).collect(Collectors.toList());
                }
            } else {
                machineToolTaskEntities = new ArrayList<>();
            }
        }
        List<Integer> ids = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(machineToolTaskEntities)) {
            ids = machineToolTaskEntities.stream().map(MachineToolTaskEntity::getId).collect(Collectors.toList());
            if (CollectionUtil.isNotEmpty(ids) && CollectionUtil.isNotEmpty(unmetToolReloadReq.getIds())) {
                ids = ids.stream().filter(integer -> unmetToolReloadReq.getIds().contains(integer)).collect(Collectors.toList());
            }
        }
        getToolList(unmetToolReloadReq.getPageNum(), unmetToolReloadReq.getPageSize(), ids, retMap, unmetToolReloadReq.getFlag(), unmetToolReloadReq.getTaskIds(), unmetToolReloadReq.getSeqs());
        return (List<ToolDemandPredictionVo>) retMap.get("toolList");
    }

    public List<IncBoxParamVo> equipmentOnlineData(EquipmentOnlineDataReq equipmentOnlineDataReq) {
        Integer warehouseId = equipmentOnlineDataReq.getWarehouseId();
        WarehouseEntity warehouseEntity = warehouseRespository.getById(warehouseId);
        if (ObjectUtil.isNotNull(warehouseEntity)) {
            String snCode = warehouseEntity.getSnCode();
            if (StringUtil.isNotEmpty(snCode)) {
                try {
                    DeviceClient deviceClient =
                            new DeviceClient(snCode, "tcp://192.168.32.107:1883", null, null, null);
                    deviceClient.connect();
                    String id = deviceClient.getIdOf("/NC_LINK_ROOT/MACHINE/CONTROLLER/TOOL_PARAM");
                    int i = getLengthByGroup(warehouseId, deviceClient, id);
                    //先Operation.GET_LENGTH取长度
                    List<Object> result = deviceClient.easyQuery(10000, new QueryRequestItem.Builder()
                            .id(id).addIndexRange(0, i - 1).build());
                    List<IncBoxParamVo> incBoxParamVos = CommonUtil.parseToolParams(result.get(0).toString());
                    return filterByCondition(incBoxParamVos, equipmentOnlineDataReq);
                } catch (Exception e) {
                    System.out.println("e = " + e);
                    return new ArrayList<>();
                }
            }
        }
        return new ArrayList<>();
    }

    private List<IncBoxParamVo> filterByCondition(List<IncBoxParamVo> incBoxParamVos, EquipmentOnlineDataReq equipmentOnlineDataReq) {
        if (CollectionUtil.isEmpty(incBoxParamVos)) {
            return new ArrayList<>();
        }
        if (StringUtils.isNotBlank(equipmentOnlineDataReq.getToolNo())) {
            incBoxParamVos = incBoxParamVos
                    .stream()
                    .filter(incBoxParamVo -> ("T" + incBoxParamVo.getName()).contains(equipmentOnlineDataReq.getToolNo()))
                    .collect(Collectors.toList());
        }
        if (StringUtils.isNotBlank(equipmentOnlineDataReq.getPosition())) {
            incBoxParamVos = incBoxParamVos
                    .stream()
                    .filter(incBoxParamVo -> {
                        LinkedHashMap<String, Object> key_value = incBoxParamVo.getKey_value();
                        //取到对应的位置信息
                        String position = key_value.getOrDefault("position", "").toString();
                        return position.contains(equipmentOnlineDataReq.getPosition());
                    })
                    .collect(Collectors.toList());
        }
        if (StringUtils.isNotBlank(equipmentOnlineDataReq.getPosition())) {
            incBoxParamVos = incBoxParamVos
                    .stream()
                    .filter(incBoxParamVo -> {
                        LinkedHashMap<String, Object> key_value = incBoxParamVo.getKey_value();
                        //取到对应的位置信息
                        String position = key_value.getOrDefault("position", "").toString();
                        return position.contains(equipmentOnlineDataReq.getPosition());
                    })
                    .collect(Collectors.toList());
        }
        if (StringUtils.isNotBlank(equipmentOnlineDataReq.getToolLength())) {
            incBoxParamVos = incBoxParamVos
                    .stream()
                    .filter(incBoxParamVo -> {
                        Double length = Double.valueOf(incBoxParamVo.getLength());
                        String lengthFormat = new DecimalFormat("######0.000").format(length);
                        Double toolLength = Double.valueOf(lengthFormat);
                        String toolLengthStr = "" + toolLength;
                        return toolLengthStr.contains(equipmentOnlineDataReq.getToolLength());
                    })
                    .collect(Collectors.toList());
        }
        if (StringUtils.isNotBlank(equipmentOnlineDataReq.getToolRadius())) {
            incBoxParamVos = incBoxParamVos
                    .stream()
                    .filter(incBoxParamVo -> {
                        Double radius = Double.valueOf(incBoxParamVo.getRadius());
                        String radiusFormat = new DecimalFormat("######0.000").format(radius);
                        Double toolRadius = Double.valueOf(radiusFormat);
                        String toolRadiusStr = "" + toolRadius;
                        return toolRadiusStr.contains(equipmentOnlineDataReq.getToolRadius());
                    })
                    .collect(Collectors.toList());
        }
        return incBoxParamVos;
    }

    public int getLengthByGroup(Integer warehouseId, DeviceClient deviceClient, String id) throws InvalidIdException, InvalidMessageException, MqttException, InvalidItemException, InvalidRequestException, TimeoutException {
        String s = equipmentGroupRepository.selectGroupTypeByEquipmentId(warehouseId);
        int i = 0;
        if (s.equals("西门子")) {
            List<Object> length = deviceClient.easyQuery(7000, new QueryRequestItem.Builder().id(id).operation(Operation.GET_LENGTH).build());
            i = Integer.parseInt(((List) length.get(0)).get(0).toString());
            //i = 2;
        } else if (s.equals("海德汉")) {
            i = warehouseRespository.selectLengthParam(warehouseId);
        } else if (s.equals("科德")) {
            //按照实际库位数量读取
            i = warehouseRespository.selectLength(warehouseId);
        }
//        switch (s) {
//            case "西门子":
//                List<Object> length = deviceClient.easyQuery(7000, new QueryRequestItem.Builder().id(id).operation(Operation.GET_LENGTH).build());
//                i = Integer.parseInt(((List) length.get(0)).get(0).toString());
//            case "海德汉":
//                i = warehouseRespository.selectLengthParam(warehouseId);
//            case "科德":
//                //按照实际库位数量读取
//                i = warehouseRespository.selectLength(warehouseId);
//        }
        return i;
    }

    ;

    public Object equipmentOnlineProgram(Integer warehouseId) throws MqttException, InterruptedException {
        WarehouseEntity warehouseEntity = warehouseRespository.getById(warehouseId);
        if (ObjectUtil.isNotNull(warehouseEntity)) {
            String snCode = warehouseEntity.getSnCode();
            if (StringUtil.isNotEmpty(snCode)) {
                DeviceClient deviceClient =
                        //new DeviceClient("1000E0DC00025E", "tcp://io.hzncc.cn:33207", null, null, null);
                        new DeviceClient(snCode, "tcp://192.168.19.99:1883", null, null, null);
                try {
                    deviceClient.connect();
                    String id = deviceClient.getIdOf("/NC_LINK_ROOT/MACHINE/CONTROLLER/PROGRAM");
                    //先Operation.GET_LENGTH取长度
                    Object o = deviceClient.easyQuery(3000, new QueryRequestItem.Builder()
                            .id(id).operation(Operation.GET_VALUE).build());
                    deviceClient.close();
                    return CommonUtil.getProgramString(o);
                } catch (Exception e) {
                    deviceClient.close();
                    log.error(e.getMessage());
                    return "";
                }
            }
        }
        return new ArrayList<>();

    }

    public List<NameNumberEntity> queryMaximumMaterialUsage() {
        LambdaQueryWrapper<ICabinetRecordEntity> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ICabinetRecordEntity::getType, "取料单");
        queryWrapper.ne(ICabinetRecordEntity::getPartType, "");
        List<ICabinetRecordEntity> toolPartEntityList = iCabinetRecordMapper.selectList(queryWrapper);
        Map<String, List<ICabinetRecordEntity>> map = toolPartEntityList.stream().collect(Collectors.groupingBy(ICabinetRecordEntity::getPartType));
        Map<String, Integer> map1 = new HashMap<>();
        Iterator<Map.Entry<String, List<ICabinetRecordEntity>>> entries = map.entrySet().iterator();
        List<NameNumberEntity> nameNumberEntities = new ArrayList<>();
        while (entries.hasNext()) {
            Map.Entry<String, List<ICabinetRecordEntity>> entry = entries.next();
            map1.put(entry.getKey(), entry.getValue().stream().filter(s -> StringUtils.isNotEmpty(s.getNumber())).mapToInt(c -> Integer.parseInt(c.getNumber())).sum());
        }
        Map<String, Integer> sortMap = sortMap(map1);
        Iterator<Map.Entry<String, Integer>> entries1 = sortMap.entrySet().iterator();
        while (entries1.hasNext()) {
            Map.Entry<String, Integer> entry = entries1.next();
            NameNumberEntity nameNumberEntity = new NameNumberEntity();
            nameNumberEntity.setName(entry.getKey());
            nameNumberEntity.setNumber(entry.getValue());
            nameNumberEntities.add(nameNumberEntity);
        }
        return nameNumberEntities;

    }

    private static Map<String, Integer> sortMap(Map<String, Integer> map) {
        //利用Map的entrySet方法，转化为list进行排序
        List<Map.Entry<String, Integer>> entryList = new ArrayList<>(map.entrySet());
        //利用Collections的sort方法对list排序
        Collections.sort(entryList, new Comparator<Map.Entry<String, Integer>>() {
            @Override
            public int compare(Map.Entry<String, Integer> o1, Map.Entry<String, Integer> o2) {
                //正序排列，倒序反过来
                return o2.getValue() - o1.getValue();
            }
        });
        //遍历排序好的list，一定要放进LinkedHashMap，因为只有LinkedHashMap是根据插入顺序进行存储
        LinkedHashMap<String, Integer> linkedHashMap = new LinkedHashMap<String, Integer>();
        int i = 6;
        for (Map.Entry<String, Integer> e : entryList
        ) {
            linkedHashMap.put(e.getKey(), e.getValue());
            i--;
            if (i <= 0) {
                break;
            }
        }
        return linkedHashMap;
    }

    public List<NameNumberEntity> queryReclaimingCategory() {
        LambdaQueryWrapper<TypeEntity> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(TypeEntity::getParentId, 435);
        List<TypeEntity> typeEntityList = typeMapper.selectList(lambdaQueryWrapper);
        LambdaQueryWrapper<TypeEntity> lambdaQueryWrapper1 = new LambdaQueryWrapper<>();
        List<TypeEntity> allTypeEntity = typeMapper.selectList(lambdaQueryWrapper1);
        List<NameNumberEntity> nameNumberEntities = new ArrayList<>();
        typeEntityList.forEach(typeEntity -> {
            NameNumberEntity nameNumberEntity = new NameNumberEntity();
            List<String> allTypeName = new ArrayList<>();
            addChild(typeEntity, allTypeEntity, allTypeName);
            if (CollectionUtil.isNotEmpty(allTypeName)) {
                LambdaQueryWrapper<ICabinetRecordEntity> queryWrapper = new LambdaQueryWrapper<>();
                queryWrapper.in(ICabinetRecordEntity::getPartno, allTypeName);
                queryWrapper.eq(ICabinetRecordEntity::getType, "取料单");
                List<ICabinetRecordEntity> list = iCabinetRecordMapper.selectList(queryWrapper);
                if (CollectionUtil.isNotEmpty(list)) {
                    nameNumberEntity.setName(typeEntity.getTypeName());
                    nameNumberEntity.setNumber(list.stream().filter(s -> StringUtils.isNotEmpty(s.getNumber())).mapToInt(c -> Integer.parseInt(c.getNumber())).sum());
                    nameNumberEntities.add(nameNumberEntity);
                } else {
                    nameNumberEntity.setName(typeEntity.getTypeName());
                    nameNumberEntity.setNumber(0);
                    nameNumberEntities.add(nameNumberEntity);
                }
            } else {
                nameNumberEntity.setName(typeEntity.getTypeName());
                nameNumberEntity.setNumber(0);
                nameNumberEntities.add(nameNumberEntity);
            }

        });
        return nameNumberEntities;

    }

    private void addChild(TypeEntity typeEntity, List<TypeEntity> typeEntityList, List<String> allTypeName) {
        List<TypeEntity> tempList = typeEntityList.stream()
                .filter(dept -> typeEntity.getId().equals(dept.getParentId()))
                .collect(Collectors.toList());
        tempList.forEach(dept -> {
            allTypeName.add(dept.getTypeName());
            addChild(dept, typeEntityList, allTypeName);
        });
    }


    public Object queryDirectRetrievalList(QryDirectRetrievalReq qryDirectRetrievalReq) {
//        PageHelper.startPage(qryDirectRetrievalReq.getPageNum(), qryDirectRetrievalReq.getPageSize());
        PageHelper.startPage(qryDirectRetrievalReq.getPageNum(), qryDirectRetrievalReq.getPageSize());


        List<DirectRetrievalVo> directRetrievalVos = toolForkInfoRespository.queryDirectRetrievalListByPartno(qryDirectRetrievalReq);
        directRetrievalVos.forEach(directRetrievalVo -> {

            if (qryDirectRetrievalReq.getTypeFlag() == 1) {
//                LambdaQueryWrapper<ToolForkInfoEntity> lambdaQueryWrapper = new LambdaQueryWrapper<>();
//                lambdaQueryWrapper.eq(ToolForkInfoEntity::getPartno,directRetrievalVo.getPartno());
//                ToolForkInfoEntity toolForkInfoEntity = toolForkInfoMapper.selectOne(lambdaQueryWrapper);
                if (StringUtils.isNotEmpty(directRetrievalVo.getIdnr())) {
                    directRetrievalVo.setPartType(directRetrievalVo.getIdnr());
                }

            } else if (qryDirectRetrievalReq.getTypeFlag() == 0) {
                LambdaQueryWrapper<AssemblyToolInventoryEntity> lambdaQueryWrapper = new LambdaQueryWrapper<>();
                lambdaQueryWrapper.eq(AssemblyToolInventoryEntity::getToolNo, directRetrievalVo.getToolNo());
                lambdaQueryWrapper.ne(AssemblyToolInventoryEntity::getType, "");
                List<AssemblyToolInventoryEntity> assemblyToolInventoryEntity = assemblyToolInventoryMapper.selectList(lambdaQueryWrapper);
                if (CollectionUtil.isNotEmpty(assemblyToolInventoryEntity)) {
                    directRetrievalVo.setType(assemblyToolInventoryEntity.get(0).getType());
                }
            }

            if (qryDirectRetrievalReq.getTypeFlag() == 1) {
                directRetrievalVo.setTotalLocationNum(inventoryLocationRespository.getTotalInventoryByPartno(directRetrievalVo.getPartno()));
            } else if (qryDirectRetrievalReq.getTypeFlag() == 0) {
                directRetrievalVo.setTotalLocationNum(inventoryLocationRespository.getTotalInventoryByToolNo(directRetrievalVo.getToolNo()));
            }
        });
        PageInfo<DirectRetrievalVo> pageInfo = new PageInfo<>(directRetrievalVos);
        Map<String, Object> retMap = new HashMap<>();
        retMap.put("list", pageInfo.getList());
        retMap.put("total", pageInfo.getTotal());
        return retMap;
//        List<DirectRetrievalVo> directRetrievalVoList = new ArrayList<>();
//        Map<String, List<DirectRetrievalVo>> map = new HashMap<>();
//        if (qryDirectRetrievalReq.getTypeFlag() == 0) {
//            map = directRetrievalVos.stream().collect(Collectors.groupingBy(DirectRetrievalVo::getToolNo));
//        } else if (qryDirectRetrievalReq.getTypeFlag() == 1) {
//            map = directRetrievalVos.stream().collect(Collectors.groupingBy(DirectRetrievalVo::getPartno));
//        }
//        Iterator<Map.Entry<String, List<DirectRetrievalVo>>> entries = map.entrySet().iterator();
//        int flag = 0;
//        int startPage = (qryDirectRetrievalReq.getPageNum() - 1) * qryDirectRetrievalReq.getPageSize();
//        int endPage = qryDirectRetrievalReq.getPageNum() * qryDirectRetrievalReq.getPageSize();
//        while (entries.hasNext()) {
//            Map.Entry<String, List<DirectRetrievalVo>> entry = entries.next();
//            if (flag < endPage) {
//                flag++;
//            } else {
//                break;
//            }
//            if (flag > startPage) {
//                DirectRetrievalVo directRetrievalVo1 = new DirectRetrievalVo();
//                List<String> idnrs = new ArrayList<>();
//                List<String> types = new ArrayList<>();
//                List<String> imgs = new ArrayList<>();
//                entry.getValue().forEach(directRetrievalVo -> {
////                    if (StringUtils.isNotEmpty(directRetrievalVo.getImage())) {
////                        directRetrievalVo.setImage(minioProp.getBaseUrl() + minioProp.getBucketName() + "/" + directRetrievalVo.getImage());
////                        imgs.add(minioProp.getBaseUrl() + minioProp.getBucketName() + "/" + directRetrievalVo.getImage());
////                    }
////                    LocationNameVo locationNameVo = inventoryLocationRespository.queryLocation(directRetrievalVo.getId());
////                    if (locationNameVo != null) {
////                        StringBuilder stringBuilder = new StringBuilder();
////                        String locationName = stringBuilder.append(locationNameVo.getTypeName()).append("-")
////                                .append(locationNameVo.getWarehouseName()).append("-库位")
////                                .append(locationNameVo.getLocationNum()).toString();
////                        directRetrievalVo.setWarehouseName(locationName);
////                    }
//                    if (qryDirectRetrievalReq.getTypeFlag() == 1 && StringUtils.isNotEmpty(directRetrievalVo.getIdnr())) {
//                        idnrs.add(directRetrievalVo.getIdnr());
//                    } else if (qryDirectRetrievalReq.getTypeFlag() == 0 && StringUtils.isNotEmpty(directRetrievalVo.getType())) {
//                        types.add(directRetrievalVo.getType());
//                    }
//                });
//                if (CollectionUtil.isNotEmpty(imgs)) {
//                    directRetrievalVo1.setImage(imgs.get(0));
//                }
//                if (qryDirectRetrievalReq.getTypeFlag() == 0) {
//                    directRetrievalVo1.setToolNo(entry.getKey());
//                } else if (qryDirectRetrievalReq.getTypeFlag() == 1) {
//                    directRetrievalVo1.setPartno(entry.getKey());
//                }
//                if (CollectionUtil.isNotEmpty(idnrs)) {
//                    directRetrievalVo1.setIdnr(idnrs.get(0));
//                }
//                if (CollectionUtil.isNotEmpty(types)) {
//                    directRetrievalVo1.setType(types.get(0));
//
//                }
//                if (qryDirectRetrievalReq.getTypeFlag() == 1) {
//                    directRetrievalVo1.setTotalLocationNum(inventoryLocationRespository.getTotalInventoryByPartno(entry.getKey()));
//                } else if (qryDirectRetrievalReq.getTypeFlag() == 0) {
//                    directRetrievalVo1.setTotalLocationNum(inventoryLocationRespository.getTotalInventoryByToolNo(entry.getKey()));
//                }
//
////            directRetrievalVo1.setTotalLocationNum(entry.getValue().stream().filter(directRetrievalVo ->ObjectUtil.isNotNull(directRetrievalVo.getTotalLocationNum())).mapToInt(DirectRetrievalVo::getTotalLocationNum).sum());
////                directRetrievalVo1.setDirectRetrievalVoList(entry.getValue());
//                if (Objects.isNull(directRetrievalVo1.getTotalLocationNum()) || directRetrievalVo1.getTotalLocationNum() == 0)
//                    directRetrievalVo1.setTotalLocationNum(0);
//                directRetrievalVoList.add(directRetrievalVo1);
//            }
//
//        }
//        PageInfo<DirectRetrievalVo> result = new PageInfo<>(directRetrievalVoList);
////        PageInfo<DirectRetrievalVo> pageInfo = new PageInfo<>(directRetrievalVos);
////        拼接图片前缀以及设置总库存
////        pageInfo.getList().forEach(directRetrievalVo -> {
////            directRetrievalVo.setImage(minioProp.getBaseUrl() + minioProp.getBucketName() + "/" + directRetrievalVo.getImage());
////            if (qryDirectRetrievalReq.getTypeFlag() == 1){
////                if (StringUtils.isNotEmpty(directRetrievalVo.getPartno())) {
////                    directRetrievalVo.setTotalLocationNum(inventoryLocationRespository.getTotalInventoryByPartno(directRetrievalVo.getPartno()));
////                }
////            }else if (qryDirectRetrievalReq.getTypeFlag() == 0){
////                if (StringUtils.isNotEmpty(directRetrievalVo.getToolNo())){
////                    Integer i = inventoryLocationRespository.getTotalInventoryByToolNo(directRetrievalVo.getToolNo());
////
////                    directRetrievalVo.setTotalLocationNum(inventoryLocationRespository.getTotalInventoryByToolNo(directRetrievalVo.getToolNo()));
////                }
////            }
////            else {
////                if (StringUtils.isNotEmpty(directRetrievalVo.getPartno())) {
////                    directRetrievalVo.setTotalLocationNum(inventoryLocationRespository.getTotalInventoryByPartno(directRetrievalVo.getPartno()));
////                }
////                if (StringUtils.isNotEmpty(directRetrievalVo.getToolNo())){
////                    Integer i = inventoryLocationRespository.getTotalInventoryByToolNo(directRetrievalVo.getToolNo());
////                    directRetrievalVo.setTotalLocationNum(inventoryLocationRespository.getTotalInventoryByToolNo(directRetrievalVo.getToolNo()));
////                }
////            }
////        });
//        Map<String, Object> retMap = new HashMap<>();
//        retMap.put("list", result.getList());
//        retMap.put("total", map.size());
//        return retMap;
    }

    public PageResult<AssemblyRetrievalVo> queryAssemblyRetrieval(QryDirectRetrievalReq qryDirectRetrievalReq) {
        LambdaQueryWrapper<AssemblyToolInventoryEntity> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(AssemblyToolInventoryEntity::getToolNo, qryDirectRetrievalReq.getToolNo());
        AssemblyToolInventoryEntity assemblyToolInventoryEntity = assemblyToolInventoryMapper.selectOne(lambdaQueryWrapper);
        List<AssemblyRetrievalVo> assemblyRetrievalVoList = new ArrayList<>();
        if (assemblyToolInventoryEntity != null) {
            LambdaQueryWrapper<ToolInventoryLocationEntity> lambdaQueryWrapper1 = new LambdaQueryWrapper<>();
            lambdaQueryWrapper1.eq(ToolInventoryLocationEntity::getAssemblyToolInventoryId, assemblyToolInventoryEntity.getId());
            lambdaQueryWrapper1.ne(ToolInventoryLocationEntity::getPhysicalInventory, 0);
            List<ToolInventoryLocationEntity> toolInventoryLocationEntities = toolInventoryLocationMapper.selectList(lambdaQueryWrapper1);
            if (CollectionUtil.isNotEmpty(toolInventoryLocationEntities)) {
                toolInventoryLocationEntities.forEach(toolInventoryLocationEntity -> {
                    AssemblyRetrievalVo assemblyRetrievalVo = new AssemblyRetrievalVo();
                    assemblyRetrievalVo.setInventoryLocationId(toolInventoryLocationEntity.getInventoryLocationId());
                    LocationNameVo locationNameVo = inventoryLocationRespository.queryLocationByInventoryLocationId(toolInventoryLocationEntity.getInventoryLocationId());
                    if (locationNameVo != null) {
                        StringBuilder stringBuilder = new StringBuilder();
                        String locationName = stringBuilder.append(locationNameVo.getTypeName()).append("-")
                                .append(locationNameVo.getWarehouseName()).append("-库位")
                                .append(locationNameVo.getLocationNum()).toString();
                        assemblyRetrievalVo.setLocationName(locationName);
                    }
                    assemblyRetrievalVo.setPhysicalInventory(toolInventoryLocationEntity.getPhysicalInventory());
                    if (StringUtils.isNotEmpty(assemblyToolInventoryEntity.getToolType()))
                        assemblyRetrievalVo.setToolType(assemblyToolInventoryEntity.getToolType());
                    if (StringUtils.isNotEmpty(assemblyToolInventoryEntity.getType()))
                        assemblyRetrievalVo.setType(assemblyToolInventoryEntity.getType());
                    assemblyRetrievalVoList.add(assemblyRetrievalVo);
                });
            }
        }
        PageInfo<AssemblyRetrievalVo> result = new PageInfo<>(CommonUtil.pageList(assemblyRetrievalVoList, qryDirectRetrievalReq.getPageNum(), qryDirectRetrievalReq.getPageSize()));

        return new PageResult<>(result.getList(), (long) assemblyRetrievalVoList.size());
    }


    public Object equipmentOnlineDataReload(EquipmentOnlineDataReq equipmentOnlineDataReq) {
        List<MachineToolDataLog> resultList = new ArrayList<>();
        List<Integer> positions = machineToolDataLogRepository.groupByPoisition(equipmentOnlineDataReq.getWarehouseId());
        if (CollectionUtil.isNotEmpty(positions)) {
            positions.forEach(position -> {
                MachineToolDataLog machineToolDataLog = machineToolDataLogRepository.selectByPosition(position, equipmentOnlineDataReq.getWarehouseId(), equipmentOnlineDataReq.getToolNo(), equipmentOnlineDataReq.getToolLength(), equipmentOnlineDataReq.getToolRadius());
                if (ObjectUtil.isNotNull(machineToolDataLog)) {
                    resultList.add(machineToolDataLog);
                }
            });
        }
        return resultList;
    }

    public void exportUnmetToolList(ExportUnmetToolList exportUnmetToolList, HttpServletResponse response) {
        String outputFileName = exportUnmetToolList.getOrderEntity().getTaskId().trim() + "未满足刀具看板";
        CommonUtil.exportExcelFile(exportUnmetToolList, "/template/未满足刀具导出模板.xlsx", response, outputFileName);
    }

    public Object queryDirectRetrievalIndex(QryDirectRetrievalReq qryDirectRetrievalReq) {
        if (ObjectUtil.isNull(qryDirectRetrievalReq.getTypeFlag())) {
            return new ArrayList<>();
        }
        List<DirectRetrievalVo> resultList = new ArrayList<>();
        List<DirectRetrievalVo> pageList = new ArrayList<>();
        if (qryDirectRetrievalReq.getTypeFlag() == 1) {
            resultList = toolInventoryLocationRespository.queryDirectRetrievalToolIndex(qryDirectRetrievalReq);
            if (CollectionUtil.isNotEmpty(resultList)) {
                resultList = resultList
                        .stream()
                        .filter(directRetrievalVo -> ObjectUtil.isNotNull(directRetrievalVo.getTotalLocationNum()) && directRetrievalVo.getTotalLocationNum() > 0)
                        .collect(Collectors.toList());
                if (CollectionUtil.isNotEmpty(resultList)) {
                    pageList = CommonUtil.pageList(resultList, qryDirectRetrievalReq.getPageNum(), qryDirectRetrievalReq.getPageSize());
                    pageList.forEach(directRetrievalVo -> directRetrievalVo.setPartType(directRetrievalVo.getIdnr()));
                }
            }
        } else if (qryDirectRetrievalReq.getTypeFlag() == 0) {
            resultList = toolInventoryLocationRespository.queryDirectRetrievalAssemblyToolIndex(qryDirectRetrievalReq);
            if (CollectionUtil.isNotEmpty(resultList)) {
                resultList = resultList
                        .stream()
                        .filter(directRetrievalVo -> ObjectUtil.isNotNull(directRetrievalVo.getTotalLocationNum()) && directRetrievalVo.getTotalLocationNum() > 0)
                        .collect(Collectors.toList());
                if (CollectionUtil.isNotEmpty(resultList)) {
                    pageList = CommonUtil.pageList(resultList, qryDirectRetrievalReq.getPageNum(), qryDirectRetrievalReq.getPageSize());
                }
            }
        }
        return new PageResult<>(pageList, (long) resultList.size());
    }
}
